【bzoj 1901】Zju2112 Dynamic Rankings
Description
给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改变后的a继续回答上面的问题。
Input
第一行有两个正整数n(1≤n≤10000),m(1≤m≤10000)。
分别表示序列的长度和指令的个数。
第二行有n个数,表示a[1],a[2]……a[n],这些数都小于10^9。
接下来的m行描述每条指令
每行的格式是下面两种格式中的一种。
Q i j k 或者 C i t
Q i j k (i,j,k是数字,1≤i≤j≤n, 1≤k≤j-i+1)
表示询问指令,询问a[i],a[i+1]……a[j]中第k小的数。
C i t (1≤i≤n,0≤t≤10^9)表示把a[i]改变成为t
m,n≤10000
Output
对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。
Sample Input
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
Sample Output
3
6
带修改的整体二分……整体二分不会改变操作顺序,把修改也加进操作就可以了√
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define LL long long 5 using namespace std; 6 const int N=5e4+5; 7 const int inf=1e9; 8 int n,m,cnt,qid,id,temp,x[N],ans[N],tr[N]; 9 bool f[N]; 10 char ch[5]; 11 struct node{int op,l,r,k,num;}a[N],tmp[N]; 12 int lowbit(int x){return x&(-x);} 13 void insert(int x,int c){while(x<=n)tr[x]+=c,x+=lowbit(x);} 14 int query(int x){int ans=0;while(x)ans+=tr[x],x-=lowbit(x);return ans;} 15 int read() 16 { 17 int x=0,f=1;char c=getchar(); 18 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 19 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 20 return x*f; 21 } 22 void work(int ql,int qr,int L,int R) 23 { 24 if(ql>qr||L>R)return; 25 if(L==R){for(int i=ql;i<=qr;i++)if(a[i].op)ans[a[i].num]=L;return;} 26 int mid=(L+R)>>1,h1=ql,h2=ql; 27 for(int i=ql;i<=qr;i++) 28 if(a[i].op) 29 { 30 temp=query(a[i].r)-query(a[i].l-1); 31 if(temp>=a[i].k)f[i]=true,h2++; 32 else f[i]=false,a[i].k-=temp; 33 } 34 else 35 { 36 if(a[i].num<=mid)f[i]=true,h2++,insert(a[i].l,a[i].k); 37 else f[i]=false; 38 } 39 for(int i=ql;i<=qr;i++)if((!a[i].op)&&f[i])insert(a[i].l,-a[i].k); 40 for(int i=ql;i<=qr;i++) 41 if(f[i])tmp[h1++]=a[i]; 42 else tmp[h2++]=a[i]; 43 for(int i=ql;i<=qr;i++)a[i]=tmp[i]; 44 work(ql,h1-1,L,mid);work(h1,qr,mid+1,R); 45 } 46 int main() 47 { 48 n=read();m=read(); 49 for(int i=1;i<=n;i++)x[i]=read(),a[++cnt]=(node){0,i,0,1,x[i]}; 50 for(int i=1;i<=m;i++) 51 { 52 scanf("%s",ch+1); 53 if(ch[1]=='Q') 54 { 55 a[++cnt].op=1;a[cnt].num=++qid; 56 a[cnt].l=read();a[cnt].r=read();a[cnt].k=read(); 57 } 58 else 59 { 60 id=read();temp=read(); 61 a[++cnt]=(node){0,id,0,-1,x[id]}; 62 a[++cnt]=(node){0,id,0,1,x[id]=temp}; 63 } 64 } 65 work(1,cnt,-inf,inf); 66 for(int i=1;i<=qid;i++)printf("%d\n",ans[i]); 67 return 0; 68 }
带修改的主席树……外面要套个树状数组。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define LL long long 5 using namespace std; 6 const int N=2e4+5; 7 int n,m,cnt,tot,id,tx,ty; 8 int A[N],B[N],C[N],a[N],tmp[N],rt[N],xx[N],yy[N]; 9 int lc[N*200],rc[N*200],sum[N*200]; 10 char op[3]; 11 int read() 12 { 13 int x=0,f=1;char c=getchar(); 14 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 15 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 16 return x*f; 17 } 18 int lowbit(int x){return x&(-x);} 19 void ins(int& x,int last,int L,int R,int num,int c) 20 { 21 x=++tot;lc[x]=lc[last];rc[x]=rc[last];sum[x]=sum[last]+c; 22 if(L==R)return;int mid=(L+R)>>1; 23 if(num<=mid)ins(lc[x],lc[last],L,mid,num,c); 24 else ins(rc[x],rc[last],mid+1,R,num,c); 25 } 26 void add(int x,int c) 27 { 28 id=lower_bound(tmp+1,tmp+cnt+1,a[x])-tmp; 29 for(int i=x;i<=n;i+=lowbit(i))ins(rt[i],rt[i],1,cnt,id,c); 30 } 31 int query(int L,int R,int num) 32 { 33 if(L==R)return L; 34 int ans=0,mid=(L+R)>>1; 35 for(int i=1;i<=tx;i++)ans-=sum[lc[xx[i]]]; 36 for(int i=1;i<=ty;i++)ans+=sum[lc[yy[i]]]; 37 if(num<=ans) 38 { 39 for(int i=1;i<=tx;i++)xx[i]=lc[xx[i]]; 40 for(int i=1;i<=ty;i++)yy[i]=lc[yy[i]]; 41 return query(L,mid,num); 42 } 43 else 44 { 45 for(int i=1;i<=tx;i++)xx[i]=rc[xx[i]]; 46 for(int i=1;i<=ty;i++)yy[i]=rc[yy[i]]; 47 return query(mid+1,R,num-ans); 48 } 49 } 50 int main() 51 { 52 n=read();m=read();cnt=n; 53 for(int i=1;i<=n;i++)tmp[i]=a[i]=read(); 54 for(int i=1;i<=m;i++) 55 { 56 scanf("%s",op+1); 57 A[i]=read();B[i]=read(); 58 if(op[1]=='Q')C[i]=read(); 59 else tmp[++cnt]=B[i]; 60 } 61 sort(tmp+1,tmp+cnt+1); 62 cnt=unique(tmp+1,tmp+cnt+1)-tmp-1; 63 for(int i=1;i<=n;i++)add(i,1); 64 for(int i=1;i<=m;i++) 65 if(C[i]) 66 { 67 tx=ty=0; 68 for(int j=A[i]-1;j;j-=lowbit(j))xx[++tx]=rt[j]; 69 for(int j=B[i];j;j-=lowbit(j))yy[++ty]=rt[j]; 70 printf("%d\n",tmp[query(1,cnt,C[i])]); 71 } 72 else add(A[i],-1),a[A[i]]=B[i],add(A[i],1); 73 return 0; 74 }