【模板】 带修改主席树

也就是树状数组加线段树

 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 }

猜你喜欢

转载自www.cnblogs.com/xiaobuxie/p/11391864.html