ZOJ2112 BZOJ1901 Dynamic Rankings 树套树 带修改的区间第k小

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2112

树套树,线段树套splay或者主席树套树状数组,我抄了一下hzwer的代码在zoj上过不了因为zoj的数据比较大不能像hzwer那种写法一样写成nlognlogn的空间。

没有bzoj权限号也不想再写一遍,随便放个代码在这里好惹。

https://www.cnblogs.com/kuangbin/p/3308118.html  <-----这个写法的空间复杂度可以过(就是把树状数组放到外面直接搞),所以ctm我为什么抄hzwer的代码。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 const int maxn=50010;
 7 using namespace std;
 8 char s[3]={}; int n,m;
 9 int val[maxn]={},a[maxn]={},b[maxn]={},k[maxn]={};
10 int num[maxn*2]={},tot=0,flag[maxn]={};
11 int sum[maxn*50],lc[maxn*50],rc[maxn*50];
12 int rt[maxn]={},siz=0;
13 int ll[maxn]={},rr[maxn]={},xx,yy;
14 void build(int l,int r,int las,int &rot,int z,int v){
15     rot=++siz; sum[rot]=sum[las]+v; lc[rot]=lc[las]; rc[rot]=rc[las];
16     if(l==r)return;
17     int mid=(l+r)/2;
18     if(z<=mid)build(l,mid,lc[las],lc[rot],z,v);
19     else build(mid+1,r,rc[las],rc[rot],z,v);
20 }
21 int query(int l,int r,int z){
22     if(l==r)return l;
23     int suml=0,sumr=0;
24     for(int i=1;i<=xx;i++)suml+=sum[lc[ll[i]]];
25     for(int i=1;i<=yy;i++)sumr+=sum[lc[rr[i]]];
26     int mid=(l+r)/2;
27     if(sumr-suml>=z){
28         for(int i=1;i<=xx;i++)ll[i]=lc[ll[i]];
29         for(int i=1;i<=yy;i++)rr[i]=lc[rr[i]];
30         return query(l,mid,z);
31     }
32     else{
33         for(int i=1;i<=xx;i++)ll[i]=rc[ll[i]];
34         for(int i=1;i<=yy;i++)rr[i]=rc[rr[i]];
35         return query(mid+1,r,z-(sumr-suml));
36     }
37 }
38 int main(){
39     int T;scanf("%d",&T);
40     while(T-->0){
41         scanf("%d%d",&n,&m);
42         tot=0;siz=0;
43         memset(rt,0,sizeof(rt));memset(sum,0,sizeof(sum));
44         memset(rc,0,sizeof(rc));memset(lc,0,sizeof(lc));
45         memset(flag,0,sizeof(flag));
46         for(int i=1;i<=n;i++){scanf("%d",&val[i]);num[++tot]=val[i];}
47         for(int i=1;i<=m;i++){
48             scanf("%s",s);scanf("%d%d",&a[i],&b[i]);
49             if(s[0]=='C')num[++tot]=b[i];
50             else{scanf("%d",&k[i]);flag[i]=1;}
51         }
52         sort(num+1,num+tot+1);
53         tot=unique(num+1,num+tot+1)-num-1;
54         for(int i=1;i<=n;i++){
55             val[i]=lower_bound(num+1,num+1+tot,val[i])-num;
56             for(int j=i;j<=n;j+=(j&-j))
57                 build(1,tot,rt[j],rt[j],val[i],1);
58         }
59         for(int i=1;i<=m;i++){
60             if(flag[i]){
61                 xx=0;yy=0;a[i]--;//cout<<a[i]<<b[i]<<endl;
62                 for(int j=a[i];j;j-=(j&-j))ll[++xx]=rt[j];
63                 for(int j=b[i];j;j-=(j&-j))rr[++yy]=rt[j];
64                 printf("%d\n",num[query(1,tot,k[i])]);
65             }
66             else{
67                 for(int j=a[i];j<=n;j+=(j&-j))build(1,tot,rt[j],rt[j],val[a[i]],-1);
68                 val[a[i]]=lower_bound(num+1,num+1+tot,b[i])-num;
69                 for(int j=a[i];j<=n;j+=(j&-j))build(1,tot,rt[j],rt[j],val[a[i]],1);
70             }
71         }
72     }
73     return 0;
74 }
并无软用的代码,嘻嘻

所以直接找可持久化线段树的题好了,找主席树出来的都是什么jb。

 

 

 

posted @ 2018-04-08 16:27  鲸头鹳  阅读(173)  评论(0编辑  收藏  举报