The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with the query like to simply find the k-th smallest number of the given N numbers. They have developed a more powerful system such that for N numbers a[1], a[2], ..., a[N], you can ask it like: what is the k-th smallest number of a[i], a[i+1], ..., a[j]? (For some i<=j, 0<k<=j+1-i that you have given to it). More powerful, you can even change the value of some a[i], and continue to query, all the same.
Your task is to write a program for this computer, which
- Reads N numbers from the input (1 <= N <= 50,000)
- Processes M instructions of the input (1 <= M <= 10,000). These instructions
include querying the k-th smallest number of a[i], a[i+1], ..., a[j] and change
some a[i] to t.
Input
The first line of the input is a single number X (0 < X <= 4), the number
of the test cases of the input. Then X blocks each represent a single test case.
The first line of each block contains two integers N and M, representing N numbers
and M instruction. It is followed by N lines. The (i+1)-th line represents the
number a[i]. Then M lines that is in the following format
Q i j k or
C i t
It represents to query the k-th number of a[i], a[i+1], ..., a[j] and change
some a[i] to t, respectively. It is guaranteed that at any time of the operation.
Any number a[i] is a non-negative integer that is less than 1,000,000,000.
There're NO breakline between two continuous test cases.
Output
For each querying operation, output one integer to represent the result. (i.e.
the k-th smallest number of a[i], a[i+1],..., a[j])
There're NO breakline between two continuous test cases.
Sample Input
2
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
Sample Output
3
6
3
6
不知道为何,ZOJ上交这道题要FQ,BZOJ上有这道题,还TM是权限题,估计是偷的(鄙视BZOJ)。
因为有修改操作,考虑保持原有的主席树结构,假设i位置上的数变化,那么要修改主席树中i及i以后的位置,如果一个一个修改肯定超时,可以考虑将修改的时间摊到查询上去,用Bit维护修改操作,记为前缀和,很好脑补。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 using namespace std; 6 const int maxn=60010; 7 const int maxm=2500010; 8 int tot,cnt,hash[maxn],a[maxn]; 9 int sum[maxm],ch[maxm][2],rt[maxn],bit[maxn]; 10 int use[maxn],n; 11 struct Ask{ 12 int l,r,k; 13 }q[maxn]; 14 15 void Insert(int pre,int &rt,int l,int r,int g,int d){ 16 rt=++cnt; 17 ch[rt][0]=ch[pre][0]; 18 ch[rt][1]=ch[pre][1]; 19 sum[rt]=sum[pre]+d; 20 if(l==r)return; 21 int mid=(l+r)>>1; 22 if(mid>=g)Insert(ch[pre][0],ch[rt][0],l,mid,g,d); 23 else Insert(ch[pre][1],ch[rt][1],mid+1,r,g,d); 24 } 25 26 void Modify(int p,int g,int d){ 27 while(p<=n){ 28 Insert(bit[p],bit[p],1,tot,g,d); 29 p+=p&(-p); 30 } 31 } 32 33 int Query(int pre,int rt,int l,int r,int k,int L,int R){ 34 if(l==r)return l; 35 int mid=(l+r)>>1,p=R,c=0; 36 while(p){c+=sum[ch[use[p]][0]];p-=p&(-p);}p=L-1; 37 while(p){c-=sum[ch[use[p]][0]];p-=p&(-p);} 38 c+=sum[ch[rt][0]]-sum[ch[pre][0]]; 39 if(c>=k){ 40 p=R; 41 while(p){use[p]=ch[use[p]][0];p-=p&(-p);}p=L-1; 42 while(p){use[p]=ch[use[p]][0];p-=p&(-p);} 43 return Query(ch[pre][0],ch[rt][0],l,mid,k,L,R); 44 } 45 else{ 46 k-=c;p=R; 47 while(p){use[p]=ch[use[p]][1];p-=p&(-p);}p=L-1; 48 while(p){use[p]=ch[use[p]][1];p-=p&(-p);} 49 return Query(ch[pre][1],ch[rt][1],mid+1,r,k,L,R); 50 } 51 52 } 53 54 int Solve(int l,int r,int k){ 55 int p=l-1; 56 while(p){use[p]=bit[p];p-=p&(-p);}p=r; 57 while(p){use[p]=bit[p];p-=p&(-p);} 58 return Query(rt[l-1],rt[r],1,tot,k,l,r); 59 } 60 61 void Init(){ 62 memset(rt,0,sizeof(rt));cnt=0; 63 memset(bit,0,sizeof(bit)); 64 } 65 66 bool cmp(int a,int b){ 67 return a>b; 68 } 69 char op[5]; 70 int main(){ 71 int T,Q; 72 scanf("%d",&T); 73 while(T--){ 74 Init(); 75 scanf("%d%d",&n,&Q); 76 for(int i=1;i<=n;i++) 77 scanf("%d",&a[i]); 78 tot=n; 79 for(int i=1;i<=Q;i++){ 80 scanf("%s",op); 81 if(op[0]=='Q') 82 scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k); 83 else{ 84 scanf("%d%d",&q[i].l,&q[i].k); 85 a[++tot]=q[i].k;q[i].r=-1; 86 } 87 } 88 for(int i=1;i<=tot;i++) 89 hash[i]=a[i]; 90 sort(hash+1,hash+tot+1); 91 for(int i=1;i<=tot;i++) 92 a[i]=lower_bound(hash+1,hash+tot+1,a[i])-hash; 93 94 for(int i=1;i<=n;i++) 95 Insert(rt[i-1],rt[i],1,tot,a[i],1); 96 for(int i=1,head=n;i<=Q;i++){ 97 if(q[i].r==-1){ 98 Modify(q[i].l,a[q[i].l],-1); 99 Modify(q[i].l,a[++head],1); 100 a[q[i].l]=a[head]; 101 } 102 else 103 printf("%d ",hash[Solve(q[i].l,q[i].r,q[i].k)]); 104 } 105 } 106 return 0; 107 }
2016年6月9日重打了一遍……
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 using namespace std; 6 const int maxn=60010; 7 const int maxm=2500010; 8 char op[10]; 9 int n,Q,T,use[maxn]; 10 int qa[maxn],qb[maxn],qk[maxn]; 11 int tot,cnt,ch[maxm][2],sum[maxm]; 12 int a[maxn],hash[maxn],bit[maxn],rt[maxn]; 13 void Insert(int pre,int &rt,int l,int r,int g,int d){ 14 rt=++cnt; 15 ch[rt][0]=ch[pre][0]; 16 ch[rt][1]=ch[pre][1]; 17 sum[rt]=sum[pre]+d; 18 if(l==r)return; 19 if(l+r>>1>=g)Insert(ch[pre][0],ch[rt][0],l,l+r>>1,g,d); 20 else Insert(ch[pre][1],ch[rt][1],(l+r>>1)+1,r,g,d); 21 } 22 void Modify(int p,int g,int d){ 23 while(p<=n){ 24 Insert(bit[p],bit[p],1,tot,g,d); 25 p+=p&(-p); 26 } 27 } 28 int Query(int pre,int rt,int l,int r,int k,int L,int R){ 29 if(l==r)return l; 30 int c=sum[ch[rt][0]]-sum[ch[pre][0]],p=R; 31 while(p){c+=sum[ch[use[p]][0]];p-=p&(-p);}p=L-1; 32 while(p){c-=sum[ch[use[p]][0]];p-=p&(-p);} 33 if(c>=k){p=R; 34 while(p){use[p]=ch[use[p]][0];p-=p&(-p);}p=L-1; 35 while(p){use[p]=ch[use[p]][0];p-=p&(-p);} 36 return Query(ch[pre][0],ch[rt][0],l,l+r>>1,k,L,R); 37 } 38 else{p=R; 39 while(p){use[p]=ch[use[p]][1];p-=p&(-p);}p=L-1; 40 while(p){use[p]=ch[use[p]][1];p-=p&(-p);} 41 return Query(ch[pre][1],ch[rt][1],(l+r>>1)+1,r,k-c,L,R); 42 } 43 } 44 int Solve(int i){ 45 int p=qb[i]; 46 while(p){use[p]=bit[p];p-=p&(-p);}p=qa[i]-1; 47 while(p){use[p]=bit[p];p-=p&(-p);} 48 return Query(rt[qa[i]-1],rt[qb[i]],1,tot,qk[i],qa[i],qb[i]); 49 } 50 void Init(){ 51 memset(bit,0,sizeof(bit)); 52 cnt=0;tot=n; 53 } 54 int main(){ 55 #ifndef ONLINE_JUDGE 56 freopen("dynrank.in","r",stdin); 57 freopen("dynrank.out","w",stdout); 58 #endif 59 scanf("%d",&T); 60 while(T--){ 61 scanf("%d%d",&n,&Q);Init(); 62 for(int i=1;i<=n;i++){ 63 scanf("%d",&a[i]); 64 hash[i]=a[i]; 65 } 66 for(int i=1;i<=Q;i++){ 67 scanf("%s",op); 68 if(op[0]=='Q')scanf("%d%d%d",&qa[i],&qb[i],&qk[i]); 69 else{ 70 scanf("%d%d",&qa[i],&qk[i]); 71 tot++;hash[tot]=a[tot]=qk[i];qb[i]=-1; 72 } 73 } 74 sort(hash+1,hash+tot+1); 75 for(int i=1;i<=tot;i++) 76 a[i]=lower_bound(hash+1,hash+tot+1,a[i])-hash; 77 for(int i=1;i<=n;i++)Insert(rt[i-1],rt[i],1,tot,a[i],1); 78 for(int i=1,p=n;i<=Q;i++){ 79 if(qb[i]==-1){ 80 Modify(qa[i],a[qa[i]],-1); 81 Modify(qa[i],a[++p],1); 82 a[qa[i]]=a[p]; 83 } 84 else 85 printf("%d ",hash[Solve(i)]); 86 } 87 } 88 return 0; 89 }
还打了一个强大的整体二分。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 const int maxn=200010; 6 int T,n,Q,cntQ; 7 int num[maxn],ans[maxn],bit[maxn]; 8 char op[10]; 9 struct Node{ 10 int x,y,k,id,tp; 11 }a[maxn],t1[maxn],t2[maxn]; 12 //tp==1 add; tp==2 del; tp==3 query; 13 14 void Add(int x,int d){ 15 while(x<=n){ 16 bit[x]+=d; 17 x+=x&(-x); 18 } 19 } 20 21 int Query(int x){ 22 int ret=0; 23 while(x){ 24 ret+=bit[x]; 25 x-=x&(-x); 26 } 27 return ret; 28 } 29 30 void Solve(int h,int t,int l,int r){ 31 if(l==r){ 32 for(int i=h;i<=t;i++) 33 if(a[i].tp==3)ans[a[i].id]=l; 34 return; 35 } 36 if(h>t)return; 37 int p1=0,p2=0,d; 38 for(int i=h;i<=t;i++){ 39 if(a[i].tp==3){ 40 d=Query(a[i].y)-Query(a[i].x-1); 41 if(d>=a[i].k)t1[++p1]=a[i]; 42 else{ 43 a[i].k-=d; 44 t2[++p2]=a[i]; 45 } 46 } 47 else if(a[i].k<=l+r>>1){ 48 if(a[i].tp==1)Add(a[i].x,1); 49 if(a[i].tp==2)Add(a[i].x,-1); 50 t1[++p1]=a[i]; 51 } 52 else t2[++p2]=a[i]; 53 } 54 for(int i=h;i<=t;i++){ 55 if(a[i].k<=l+r>>1){ 56 if(a[i].tp==1)Add(a[i].x,-1); 57 if(a[i].tp==2)Add(a[i].x,1); 58 } 59 } 60 for(int i=1;i<=p1;i++)a[h+i-1]=t1[i]; 61 for(int i=1;i<=p2;i++)a[h+i+p1-1]=t2[i]; 62 Solve(h,h+p1-1,l,l+r>>1); 63 Solve(h+p1,t,(l+r>>1)+1,r); 64 } 65 66 int main(){ 67 #ifndef ONLINE_JUDGE 68 freopen("dynrank.in","r",stdin); 69 freopen("dynrank.out","w",stdout); 70 #endif 71 scanf("%d",&T); 72 while(T--){ 73 scanf("%d%d",&n,&Q); 74 for(int i=1;i<=n;i++){ 75 scanf("%d",&a[i].k); 76 a[i].x=i;a[i].tp=1; 77 num[i]=a[i].k; 78 } 79 cntQ=0; 80 int x,y,k; 81 while(Q--){ 82 scanf("%s",op); 83 if(op[0]=='Q'){ 84 scanf("%d%d%d",&x,&y,&k); 85 a[++n].id=++cntQ;a[n].tp=3; 86 a[n].x=x;a[n].y=y;a[n].k=k; 87 } 88 else{ 89 scanf("%d%d",&x,&k); 90 a[++n].tp=2;a[n].x=x;a[n].k=num[x]; 91 a[++n].tp=1;a[n].x=x;a[n].k=k;num[x]=k; 92 } 93 } 94 Solve(1,n,1,1000000000); 95 for(int i=1;i<=cntQ;i++) 96 printf("%d ",ans[i]); 97 } 98 return 0; 99 }