[bzoj1901]: Zju2112 Dynamic Rankings
2016-01-13 14:28
162 查看
人生第一道树套树。。(虽然暑假就写了= =)
这题是树状数组里面套个可持久化线段树。。。一开始想反了然后发现完全不会写TAT
一般的树状数组操作的时候是直接修改数组里的值的,套上可持久化线段树后就变成在相应的那颗线段树里面修改了。
修改操作就一个一个改,但查询第k大的时候要先把对应的线段树都存起来,然后一起算。。。
具体见代码吧= =
View Code
这题是树状数组里面套个可持久化线段树。。。一开始想反了然后发现完全不会写TAT
一般的树状数组操作的时候是直接修改数组里的值的,套上可持久化线段树后就变成在相应的那颗线段树里面修改了。
修改操作就一个一个改,但查询第k大的时候要先把对应的线段树都存起来,然后一起算。。。
具体见代码吧= =
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #define rep1()for(register int i=1;i<=len1;i++) #define rep2()for(register int i=1;i<=len2;i++) using namespace std; const int maxn=20233; int num[maxn*17*17],lc[maxn*17*17],rc[maxn*17*17],rt[maxn]; int L[20],R[20]; struct zs{ int num,id; }a[maxn]; struct ask{ int l,r,x; bool id; }q[10023]; int b[maxn],c[maxn]; int i,j,cnt,n,m,tot,len1,len2; int ra;char rx; inline int read(){ rx=getchar(),ra=0; while(rx<'0'||rx>'9')rx=getchar(); while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra; } inline int sum1(){int sum=0;rep1()sum+=num[L[i]];return sum;} inline int sum2(){int sum=0;rep2()sum+=num[R[i]];return sum;} inline void run1(int x){for(len1=0;x;x-=x&(-x))L[++len1]=rt[x];} inline void run2(int x){for(len2=0;x;x-=x&(-x))R[++len2]=rt[x];} void ins(int pre,int &now,int l,int r,int v){ now=++tot;num[now]=num[pre]+1; if(l==r)return;int mid=(l+r)>>1; if(v<=mid)rc[now]=rc[pre],ins(lc[pre],lc[now],l,mid,v); else lc[now]=lc[pre],ins(rc[pre],rc[now],mid+1,r,v); } int query(int l,int r,int k){ if(l==r)return l; int mid=(l+r)>>1,lsize=0; rep1()lsize-=num[lc[L[i]]];rep2()lsize+=num[lc[R[i]]]; if(lsize>=k){ rep1()L[i]=lc[L[i]];rep2()R[i]=lc[R[i]]; return query(l,mid,k); }else{ rep1()L[i]=rc[L[i]];rep2()R[i]=rc[R[i]]; return query(mid+1,r,k-lsize); } } void change(int pre,int &now,int l,int r,int v,bool del){ now=++tot,num[now]=num[pre]-(del?1:-1); if(l==r)return;int mid=(l+r)>>1; if(v<=mid)rc[now]=rc[pre],change(lc[pre],lc[now],l,mid,v,del); else lc[now]=lc[pre],change(rc[pre],rc[now],mid+1,r,v,del); } void build(int l,int r,int &x){ x=++tot; if(l==r)build(l,(l+r)>>1,lc[x]),build(((l+r)>>1)+1,r,rc[x]); } bool cmp(zs a,zs b){return a.num<b.num;} int main(){ n=read(),m=read();cnt=n; for(i=1;i<=n;i++)a[i].num=read(),a[i].id=i;char rx; for(i=1;i<=m;i++){ for(rx=getchar();rx!='Q'&&rx!='C';rx=getchar()); q[i].id=(rx=='Q'); if(q[i].id)q[i].l=read(),q[i].r=read(),q[i].x=read(); else q[i].l=read(),a[++cnt].num=q[i].x=read(),a[cnt].id=i+n; } sort(a+1,a+1+cnt,cmp);int tmp=cnt; for(i=1,cnt=0;i<=tmp;i++){ if(i==1||a[i].num!=a[i-1].num)c[++cnt]=a[i].num; b[a[i].id]=cnt;if(a[i].id>n)q[a[i].id-n].x=cnt; } build(1,cnt,rt[0]);for(i=1;i<=n;i++)rt[i]=rt[0]; // for(i=1;i<=m;i++)if(q[i].id)printf(" %d\n",q[i].x); for(i=1;i<=n;i++)for(j=i;j<=n;j+=j&(-j))ins(rt[j],rt[j],1,cnt,b[i]); for(i=1;i<=m;i++){ if(q[i].id){ run1(q[i].l-1),run2(q[i].r); // printf(" %d--%d %d %d\n",q[i].l,q[i].r,len1,len2); // for(j=1;j<=len1;j++)printf(" %d",L[j]);puts("!!");for(j=1;j<=len2;j++)printf(" %d",R[j]);puts("");puts("!"); printf("%d\n",c[query(1,cnt,q[i].x)]); } else { for(j=q[i].l;j<=n;j+=j&(-j))change(rt[j],rt[j],1,cnt,b[q[i].l],1); for(j=q[i].l;j<=n;j+=j&(-j))change(rt[j],rt[j],1,cnt,q[i].x,0); b[q[i].l]=q[i].x; } } return 0; }
View Code
相关文章推荐
- String.Format数字格式化输出 {0:N2} {0:D2} {0:C2
- 硬盘的读写原理
- sqlserver自定义聚集函数
- DEBUG: 此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态。
- Codeforces Educational Codeforces Round 5 D. Longest k-Good Segment 尺取法
- spring-注解
- java后台与硬件对接经验
- div弹出层的效果带关闭按钮
- Bootstrap中的网格系统
- 设计模式(十一):中介者模式
- BT下载会损害硬盘吗
- 在论坛中出现的比较难的sql问题:37(动态行转列 某一行数据转为列名)
- 你确定你真的懂用户画像?
- Better shadow maps
- Linux的SOCKET编程详解
- 部署Maven web项目到tomcat服务器时,没有将lib下的jar复制过去的解决办法
- js操作svg
- javaScript解析顺序
- sql(转自http://www.imooc.com/article/2325)
- linux常用命令