首页 > 其他分享 >权值线段树

权值线段树

时间:2024-03-26 12:33:20浏览次数:16  
标签:__ cnt return 线段 权值 root self

与普通线段树并无其他区别,只不过存储的信息是每个值出现的次数罢了

理解图
image

import sys

input = lambda: sys.stdin.readline()


class Tree:
    def __init__(self, N):
        self.cnt = [0 for _ in range(N)]

    def update(self, root, l, r, x, cnt):
        if l == r:
            self.cnt[root] += cnt
            return
        mid = l + r >> 1
        if x <= mid:
            self.update(root << 1, l, mid, x, cnt)
        else:
            self.update(root << 1 | 1, mid + 1, r, x, cnt)
        self.cnt[root] = self.cnt[root << 1] + self.cnt[root << 1 | 1]

    # 值域在[ql,qr]的数出现的次数
    def query(self, root, l, r, ql, qr):
        if ql > r or qr < l:
            return 0
        if ql <= l and qr >= r:
            return self.cnt[root]
        mid = l + r >> 1
        return self.query(root << 1, l, mid, ql, qr) + self.query(root << 1 | 1, mid + 1, r, ql, qr)

    def find_kth(self, root, l, r, k):
        if l == r:
            return l
        mid = l + r >> 1
        if k <= self.cnt[root << 1]:
            return self.find_kth(root << 1, l, mid,k)
        else:
            return self.find_kth(root << 1 | 1, mid + 1, r,k - self.cnt[root << 1])


# 当值域过大时,可以采用离散化的方法!
N = 10
mytree = Tree(N * 4)
lst = [1, 2, 3, 4, 5, 5, 5, 5, 5]
for x in lst:
    mytree.update(1, 1, N, x, 1)

for i in range(1, N + 1):
    print(mytree.query(1, 1, N, i, i), end=' ')
print()
# 1 1 1 1 5 0 0 0 0 0
print(mytree.find_kth(1, 1, N, 4))
# 4

标签:__,cnt,return,线段,权值,root,self
From: https://www.cnblogs.com/gebeng/p/18096405

相关文章

  • P3924 康娜的线段树
    首先考虑每一个\(a_i\)(叶子结点)对于总期望值有多少贡献。不妨以区间\([1,8]\)建线段树,看看\(a_i=4\)的贡献是多少:区间\([1,8]\)的\(sum\)里包含一个\(4\);你一定会进入这个区间,贡献\(4\times1=4\)。区间\([1,4]\)的\(sum\)里包含一个\(4\);你有\(50\%\)概率进......
  • 线段树I
    线段树I题目链接P3372【模板】线段树1-洛谷|计算机科学教育新生态(luogu.com.cn)模板代码importsysinput=lambda:sys.stdin.readline()classNode:def__init__(self):self.val=0self.tag=0classTree:def__init__(self,......
  • CF1420D & 102012G [线段交集问题]
    CF1420DRescueNibel!首先要发现一个性质:如果一些线段有交集,那么交集一定是条线段,并且一定有其中一条线段的左端点是交集的左端点。所以方案可以转化为求其中一条线段的左端点是交集的左端点的方案数。这启发我们枚举每个点作为交集的左端点,计算至少有一条线段的左端点是这个......
  • 第二课——线段树
    上一节课讲了树状数组,也介绍了树状数组的优点与不足,这里简单回顾一下。优点:树状数组的代码非常简短,易于实现,被刘老师亲切的称为IO选手的"HelloWorld!",就是因为代码短。缺点:树状数组的缺点也非常的明显,只能处理单点修改区间查询或者区间修改单点查询的问题(以较高的效率)。而区间修......
  • CF938G-动态连通图最短xor路(线段树分治、并查集、线性基)
    link:https://codeforces.com/contest/938/problem/G[!Description]有一张连通的无向图简单图,三种操作:1、加边\((x,y,d)\)2、删边\((x,y)\)3、询问\(x\toy\)的路径中异或最小的路径(不一定是简单路径)保证每次操作后图是连通的\(1\leqn,m,q\leq2\times10^5\).这......
  • 楼房重建线段树
    link维护单调序列、点修的线段树。首先考虑一个楼房被看见的必要条件是前面没有斜率大于它的楼房,不等式可以推出来。然后本质上是维护一个从\(1\)号开始斜率单调上升的序列长度,注意,不能跳跃选择,即某栋楼房能加入序列则必须加入。线段树维护区间最大值和区间上升序列长度,由于......
  • 李超线段树
    模板题动态添加线段,求某个\(x\)对应的\(y\)最大是多少,且对应哪条直线。因为\(x\)比较小,考虑在\(x\)轴上建立线段树。把每个线段写成\(y=kx+b\)的解析式形式并求出它的定义域\([l,r]\),每条线段就可以看作是一个应用在\([l,r]\)上的区间修改。每次查询就是单点查询。......
  • P1712 [NOI2016] 区间 线段树+双指针
    //Problem://P1712[NOI2016]区间////Contest:Luogu//URL:https://www.luogu.com.cn/problem/P1712//MemoryLimit:250MB//TimeLimit:1000ms////PoweredbyCPEditor(https://cpeditor.org)#include<iostream>#include<algorithm......
  • CF1514D-区间(绝对)众数-莫队、随机化、可持久化线段树
    link:https://codeforces.com/contest/1514/problem/D很久以前小号打的场了,当时D题写的莫队,现在重新来看看。题意:给一个序列\([a_1,\dots,a_n]\),有q次询问,每次问:把\([a_l,\dots,a_r]\)划分最少几个不相交子序列,才能使得每个子序列是beautiful的。称一个序列\(a_1,\dots,a_x\)......
  • 大都市meg(线段树/树状数组+LCA)
    题目描述在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员BlueMary也开始骑着摩托车传递邮件了。不过,她经常回忆起以前在乡间漫步的情景。昔日,乡下有依次编号为1..n的n个小村庄,某些村庄之间有一些双向的土路。从每个村庄都恰好有一条路径到达村庄1(即比特堡)。并且......