bzoj1901 Zju2112 Dynamic Rankings*
bzoj1901 Zju2112 Dynamic Rankings
题意:
维护数据结构,支持区间第k大和单点修改。序列大小,操作数≤10000
题解:
构造一个树状数组,树状数组中的节点用主席树维护。一开始先插入序列中的节点,然后对于修改,就是将经过的树状数组上的主席树删除旧值,再插入新值;对于查询,还是和普通主席树一样二分,但此时的前缀和是由树状数组中数棵主席树查询节点的和得到的。反思:空间复杂度粗略计算是O(nlog^2n),常数大概是乘个7,8,在bzoj上内存达到了80M,幸好bzoj上空间给的是128M,听说原题空间是31M,规模是30000,我要是做原题早挂了!不知道怎么办QAQ
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define inc(i,j,k) for(int i=j;i<=k;i++) 5 #define maxn 10010 6 #define lb(x) x&-x 7 using namespace std; 8 9 inline int read(){ 10 char ch=getchar(); int f=1,x=0; 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} 12 while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); 13 return f*x; 14 } 15 int n,m,a[maxn],v[maxn*2],tot,root[maxn],sz[3*maxn*15*15],ch[3*maxn*15*15][2],cnt; 16 struct ask{char opt[3]; int l,r,k;}; ask asks[maxn]; 17 struct ls{int id,v;}; ls lss[maxn*2]; int lsss; 18 bool cmp(ls a,ls b){return a.v<b.v;} 19 void lisan(){ 20 inc(i,1,n)lss[++lsss]=(ls){i,a[i]}; 21 inc(i,1,m)if(asks[i].opt[0]=='C')lss[++lsss]=(ls){n+i,asks[i].k}; 22 sort(lss+1,lss+1+lsss,cmp); 23 inc(i,1,lsss){ 24 if(i==1||lss[i].v!=lss[i-1].v)tot++,v[tot]=lss[i].v; 25 if(lss[i].id<=n)a[lss[i].id]=tot;else asks[lss[i].id-n].k=tot; 26 } 27 } 28 int build(int l,int r){ 29 int x=++cnt; sz[x]=0; if(l==r)return x; 30 int mid=(l+r)>>1; ch[x][0]=build(l,mid); ch[x][1]=build(mid+1,r); return x; 31 } 32 void updseg(int &x,int y,int l,int r,int a){ 33 cnt++; ch[cnt][0]=ch[x][0]; ch[cnt][1]=ch[x][1]; sz[cnt]=sz[x]+a; x=cnt; if(l==r)return; 34 int mid=(l+r)>>1; if(y<=mid)updseg(ch[x][0],y,l,mid,a); if(y>mid)updseg(ch[x][1],y,mid+1,r,a); 35 } 36 int queryseg(int x,int ql,int qr,int l,int r){ 37 if(ql<=l&&r<=qr)return sz[x]; int mid=(l+r)>>1,q=0; 38 if(ql<=mid)q+=queryseg(ch[x][0],ql,qr,l,mid); if(mid<qr)q+=queryseg(ch[x][1],ql,qr,mid+1,r); 39 return q; 40 } 41 void updbit(int x,int y,int a){ 42 while(x<=n)updseg(root[x],y,1,tot,a),x+=lb(x); 43 } 44 int querybit(int x,int ql,int qr){ 45 int q=0; while(x>=1)q+=queryseg(root[x],ql,qr,1,tot),x-=lb(x); return q; 46 } 47 void init(){ 48 int x=build(1,tot); inc(i,1,n)root[i]=x; inc(i,1,n)updbit(i,a[i],1); 49 } 50 int query(int ql,int qr,int k){ 51 int l=1,r=tot; 52 while(1){ 53 int mid=(l+r)>>1; int x=querybit(qr,l,mid)-querybit(ql-1,l,mid); 54 if(x>=k)r=mid;else l=mid+1,k-=x; if(l==r)return l; 55 } 56 } 57 void modify(int x,int y){ 58 updbit(x,a[x],-1); updbit(x,y,1); a[x]=y; 59 } 60 int main(){ 61 n=read(); m=read(); inc(i,1,n)a[i]=read(); 62 inc(i,1,m){ 63 scanf("%s",asks[i].opt); 64 if(asks[i].opt[0]=='Q')asks[i].l=read(),asks[i].r=read(),asks[i].k=read(); 65 if(asks[i].opt[0]=='C')asks[i].l=read(),asks[i].k=read(); 66 } 67 lisan(); init(); 68 inc(i,1,m){ 69 if(asks[i].opt[0]=='Q')printf("%d\n",v[query(asks[i].l,asks[i].r,asks[i].k)]); 70 if(asks[i].opt[0]=='C')modify(asks[i].l,asks[i].k); 71 } 72 return 0; 73 }
20160813