模板 带修改主席树

Posted xiaobuxie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板 带修改主席树相关的知识,希望对你有一定的参考价值。

也就是树状数组加线段树

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=5e4+7;
 4 struct node
 5     int l,r,sum;
 6 tr[N<<3];
 7 struct quer
 8     int l,r,k,v,op;
 9 q[10000+7];
10 int rtn,Ln,Rn;
11 int a[N],b[N],rt[N<<2],L[N<<2],R[N<<2];
12 char s[2];
13 void change(int& o,int l,int r,int p,int val)
14     if(!o) o=++rtn;
15     tr[o].sum+=val;
16     if(l==r) return;
17     int m=(l+r)>>1;
18     if(p<=m) change(tr[o].l,l,m,p,val);
19     else change(tr[o].r,m+1,r,p,val);
20 
21 int query(int l,int r,int k)
22     if(l==r) return l;
23     int m=(l+r)>>1;
24     int cntl=0,cntr=0;
25     for(int i=1;i<=Ln;++i) cntl+=tr[tr[L[i]].l].sum;
26     for(int i=1;i<=Rn;++i) cntr+=tr[tr[R[i]].l].sum;
27     if(k<=cntr-cntl)
28         for(int i=1;i<=Ln;++i) L[i]=tr[L[i]].l;
29         for(int i=1;i<=Rn;++i) R[i]=tr[R[i]].l;
30         return  query(l,m,k);
31     
32     for(int i=1;i<=Ln;++i) L[i]=tr[L[i]].r;
33     for(int i=1;i<=Rn;++i) R[i]=tr[R[i]].r;
34     return query(m+1,r,k-cntl-cntr);
35 
36 int main()
37     int T;scanf("%d",&T);
38     while(T--)
39         rtn=0;
40         memset(rt,0,sizeof(rt));
41         int numn=0;
42         int n,m;scanf("%d%d",&n,&m);
43         for(int i=1;i<=n;++i) tr[i].sum=0;
44         for(int i=1;i<=n;++i) scanf("%d",&a[i]),b[++numn]=a[i];
45         for(int i=1;i<=m;++i)
46             scanf("%s",s);
47             if(s[0]==Q)
48                 scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k);
49                 q[i].op=0;
50             
51             else
52                 scanf("%d%d",&q[i].l,&q[i].v);
53                 q[i].op=1;
54                 b[++numn]=q[i].v;
55             
56         
57         sort(b+1,b+1+numn);
58         int num=unique(b+1,b+1+numn)-b-1;
59         for(int i=1;i<=n;++i)
60             a[i]=lower_bound(b+1,b+1+num,a[i])-b;
61             for(int j=i;j<=n;j+=j&(-j))
62                 change(rt[j],1,num,a[i],1);
63             
64         
65         for(int i=1;i<=m;++i)
66             if(!q[i].op)
67                 Ln=Rn=0;
68                 for(int j=q[i].l-1;j;j-=j&(-j))  L[++Ln]=rt[j];
69                 for(int j=q[i].r;j;j-=j&(-j)) R[++Rn]=rt[j];
70                 printf("%d\n",b[query(1,num,q[i].k)]);
71             
72             else
73                 for(int j=q[i].l;j<=n;j+=j&(-j)) 
74                     change(rt[j],1,num,a[q[i].l],-1);
75                 a[q[i].l]=lower_bound(b+1,b+1+num,q[i].v)-b;
76                for(int j=q[i].l;j<=n;j+=j&(-j)) change(rt[j],1,num,a[q[i].l],1);
77             
78         
79     
80     return 0;
81 

 

以上是关于模板 带修改主席树的主要内容,如果未能解决你的问题,请参考以下文章

Luogu Dynamic Ranking (带修改的主席树)

少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小

主席树区间第K大

zoj 2112 Dynamic Rankings 带修改区间第K大 动态主席树

模板主席树

不带修改的主席树