[bzoj1901]: Zju2112 Dynamic Rankings

  人生第一道树套树。。(虽然暑假就写了= =)

  这题是树状数组里面套个可持久化线段树。。。一开始想反了然后发现完全不会写TAT

  一般的树状数组操作的时候是直接修改数组里的值的,套上可持久化线段树后就变成在相应的那颗线段树里面修改了。

  修改操作就一个一个改,但查询第k大的时候要先把对应的线段树都存起来,然后一起算。。。

  具体见代码吧= =

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define rep1()for(register int i=1;i<=len1;i++)
 6 #define rep2()for(register int i=1;i<=len2;i++)
 7 using namespace std;
 8 const int maxn=20233;
 9 int num[maxn*17*17],lc[maxn*17*17],rc[maxn*17*17],rt[maxn];
10 int L[20],R[20];
11 struct zs{
12     int num,id;
13 }a[maxn];
14 struct ask{
15     int l,r,x;
16     bool id;
17 }q[10023];
18 int b[maxn],c[maxn];
19 int i,j,cnt,n,m,tot,len1,len2;
20  
21 int ra;char rx;
22 inline int read(){
23     rx=getchar(),ra=0;
24     while(rx<'0'||rx>'9')rx=getchar();
25     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
26 }
27  
28 inline int sum1(){int sum=0;rep1()sum+=num[L[i]];return sum;}
29 inline int sum2(){int sum=0;rep2()sum+=num[R[i]];return sum;}
30  
31 inline void run1(int x){for(len1=0;x;x-=x&(-x))L[++len1]=rt[x];}
32 inline void run2(int x){for(len2=0;x;x-=x&(-x))R[++len2]=rt[x];}
33  
34 void ins(int pre,int &now,int l,int r,int v){
35     now=++tot;num[now]=num[pre]+1;
36     if(l==r)return;int mid=(l+r)>>1;
37     if(v<=mid)rc[now]=rc[pre],ins(lc[pre],lc[now],l,mid,v);
38     else lc[now]=lc[pre],ins(rc[pre],rc[now],mid+1,r,v);
39 }
40 int query(int l,int r,int k){
41     if(l==r)return l;
42     int mid=(l+r)>>1,lsize=0;
43     rep1()lsize-=num[lc[L[i]]];rep2()lsize+=num[lc[R[i]]];
44     if(lsize>=k){
45         rep1()L[i]=lc[L[i]];rep2()R[i]=lc[R[i]];
46         return query(l,mid,k);
47     }else{
48         rep1()L[i]=rc[L[i]];rep2()R[i]=rc[R[i]];
49         return query(mid+1,r,k-lsize);
50     }
51 }
52 void change(int pre,int &now,int l,int r,int v,bool del){
53     now=++tot,num[now]=num[pre]-(del?1:-1);
54     if(l==r)return;int mid=(l+r)>>1;
55     if(v<=mid)rc[now]=rc[pre],change(lc[pre],lc[now],l,mid,v,del);
56     else lc[now]=lc[pre],change(rc[pre],rc[now],mid+1,r,v,del);
57 }
58 void build(int l,int r,int &x){
59     x=++tot;
60     if(l==r)build(l,(l+r)>>1,lc[x]),build(((l+r)>>1)+1,r,rc[x]);
61 }
62 bool cmp(zs a,zs b){return a.num<b.num;}
63 int main(){
64     n=read(),m=read();cnt=n;
65     for(i=1;i<=n;i++)a[i].num=read(),a[i].id=i;char rx;
66     for(i=1;i<=m;i++){
67         for(rx=getchar();rx!='Q'&&rx!='C';rx=getchar());
68         q[i].id=(rx=='Q');
69         if(q[i].id)q[i].l=read(),q[i].r=read(),q[i].x=read();
70             else q[i].l=read(),a[++cnt].num=q[i].x=read(),a[cnt].id=i+n;
71     }
72     sort(a+1,a+1+cnt,cmp);int tmp=cnt;
73      
74     for(i=1,cnt=0;i<=tmp;i++){
75         if(i==1||a[i].num!=a[i-1].num)c[++cnt]=a[i].num;
76         b[a[i].id]=cnt;if(a[i].id>n)q[a[i].id-n].x=cnt;
77     }
78     build(1,cnt,rt[0]);for(i=1;i<=n;i++)rt[i]=rt[0];
79 //  for(i=1;i<=m;i++)if(q[i].id)printf("    %d\n",q[i].x);
80     for(i=1;i<=n;i++)for(j=i;j<=n;j+=j&(-j))ins(rt[j],rt[j],1,cnt,b[i]);
81     for(i=1;i<=m;i++){
82         if(q[i].id){
83             run1(q[i].l-1),run2(q[i].r);
84     //      printf("    %d--%d       %d %d\n",q[i].l,q[i].r,len1,len2);
85     //      for(j=1;j<=len1;j++)printf("  %d",L[j]);puts("!!");for(j=1;j<=len2;j++)printf("  %d",R[j]);puts("");puts("!");
86             printf("%d\n",c[query(1,cnt,q[i].x)]);
87         }
88         else {
89             for(j=q[i].l;j<=n;j+=j&(-j))change(rt[j],rt[j],1,cnt,b[q[i].l],1);
90             for(j=q[i].l;j<=n;j+=j&(-j))change(rt[j],rt[j],1,cnt,q[i].x,0);
91             b[q[i].l]=q[i].x;
92         }
93     }
94     return 0;
95 }
View Code

 

posted @ 2016-01-13 14:28  czllgzmzl  阅读(209)  评论(0编辑  收藏  举报