权值线段树

权值线段树是什么

我们一般的线段树的节点下标是数组,而我们只要把它变成值,就能统计每个节点的数量了。  

类似于桶的实现吧。  

其实这个的线段树就是前缀和,也可以用树状数组来代替。  

至于查询k大,只要二分就可以了。  

数据范围大的时候通常先离散化数据,所以算半个离线数据结构。  

  

直接上代码

拿洛谷的平衡树模板为例。

这里由于懒得写线段树就拿树状数组代替了。  

如果开心的话手动改成线段树就可以了。  

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e6+1000;
 4 int read(){
 5     char c;int num,f=1;
 6     while(c=getchar(),!isdigit(c))if(c=='-')f=-1;num=c-'0';
 7     while(c=getchar(), isdigit(c))num=num*10+c-'0';
 8     return f*num;
 9 }
10 int order[N],act[N][2],cnt,t[N],n;
11 bool cmp(int a,int b){return a<b;}
12 int fd(int a){
13     int l=1,r=cnt,mid;
14     while(l<=r){
15         mid=(l+r)>>1;
16         if(order[mid]==a)return mid;
17         else if(order[mid]>a)r=mid-1;
18         else l=mid+1;
19     }
20     return -1;
21 }
22 void add(int x,int val){for(;x<=cnt;x+=x&-x)t[x]+=val;}
23 int query(int x){
24     int ans=0;
25     for(;x;x-=x&-x)ans+=t[x];
26     return ans;
27 }
28 void Insert(int x){add(x,1);}
29 void Del(int x){if(query(x)-query(x-1))add(x,-1);}
30 int Getrank(int x){return query(x-1)+1;}
31 int Getnum(int rk){
32     int l=0,r=cnt,mid,a,b;
33     while(l<=r){
34         mid=(l+r)>>1;
35         a=query(mid-1);
36         b=query(mid);
37         if(b>=rk&&a<rk)return order[mid];
38         if(b<rk)l=mid+1;
39         else r=mid-1;
40     }
41     return -1;
42 }
43 int Getpre(int x){return Getnum(Getrank(x)-1);}
44 int Getnxt(int x){return Getnum(query(x)+1);}
45 
46 int main()
47 {
48     n=read();
49     for(int i=1;i<=n;i++){
50         act[i][0]=read();
51          act[i][1]=read();
52         order[++cnt]=act[i][1];
53     }
54     sort(order+1,order+1+cnt,cmp);
55     cnt=unique(order+1,order+1+cnt)-order;
56     for(int i=1;i<=n;i++){
57         int opt=act[i][0],x=fd(act[i][1]);
58         if(opt==1)Insert(x);
59         if(opt==2)Del(x);
60         if(opt==3)printf("%d
",Getrank(x));
61         if(opt==4)printf("%d
",Getnum(act[i][1]));
62         if(opt==5)printf("%d
",Getpre(x));
63         if(opt==6)printf("%d
",Getnxt(x));
64     }
65     return 0;
66 }
View Code
原文地址:https://www.cnblogs.com/onglublog/p/9986492.html