zoj2112
这道题是要求待修改的区间第k值,看的kuangbin的树状数组加主席树,这种方法是离线的。本来是想做hdu5412的,结果超时,所以只能交了zoj2110。没什么多说的,就是模板题。如果要求第k大,只要做相应的修改就行了,有多种修改的方法,只要能的出正确答案就行。
参考代码:http://www.cnblogs.com/kuangbin/p/3308118.html
(今天为了看书,没有吃包子,只吃了面包,本来想着反正有番茄酱,但是看到队友吃包子,还是各种口水流)
2015.8.31:
回忆了一下模板。但是写时还是要注意细节。不过只要理解了原理,什么时候都能写,就是时间长短的问题。今天中午买了一个包子,结果划卡划多了,结果又多给了一个,吃的那叫一个痛哭流涕(因为菜太辣了!)。
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; #define N 50010 #define M 10010 #define Q 2600000 struct querynode{ int type; int l; int r; int k; }; int c[Q],lson[Q],rson[Q]; int T[N],S[N],use[N]; int newid[2*N]; int num[N]; bool usemark[N]; querynode queryarray[M]; int n,m; int tot; void lisanhua(){ sort(newid+1,newid+m+1); m=unique(newid+1,newid+m+1)-(newid+1); } int build(int l,int r){ int root=tot++; c[root]=0; if(l<r){ int middle=(l+r)>>1; lson[root]=build(l,middle); rson[root]=build(middle+1,r); } else{ lson[root]=-1; rson[root]=-1; } return root; } int insert(int froroot,int anum,int cou){ int root=tot++,temproot=root; int l=1,r=m; c[root]=c[froroot]+cou; while(l<r){ int middle=(l+r)>>1; if(anum<=middle){ r=middle; lson[temproot]=tot++; rson[temproot]=rson[froroot]; temproot=lson[temproot]; froroot=lson[froroot]; } else{ l=middle+1; lson[temproot]=lson[froroot]; rson[temproot]=tot++; temproot=rson[temproot]; froroot=rson[froroot]; } c[temproot]=c[froroot]+cou; } return root; } int numhash(int x){ return lower_bound(newid+1,newid+m+1,x)-newid; } int lowbit(int x){ return (~x+1)&x; } void modify(int x,int anum,int cou){ while(x<=n){ S[x]=insert(S[x],anum,cou); x=x+lowbit(x); } } int sum(int x){ int ans=0; while(x>0){ ans+=c[lson[use[x]]]; x=x-lowbit(x); } return ans; } int query(int left,int right,int k){ int l=1,r=m; int tempr=T[right],templ=T[left-1]; for(int i=right;i>0;i=i-lowbit(i)){ use[i]=S[i]; } for(int i=left-1;i>0;i=i-lowbit(i)){ use[i]=S[i]; } while(l<r){ int middle=(l+r)>>1; int cnt=sum(right)+c[lson[tempr]]-(sum(left-1)+c[lson[templ]]); if(cnt>=k){ r=middle; memset(usemark,false,sizeof(usemark)); for(int i=right;i>0;i=i-lowbit(i)){ use[i]=lson[use[i]]; usemark[i]=true; } for(int i=left-1;i>0;i=i-lowbit(i)){ if(!usemark[i]){ use[i]=lson[use[i]]; } } tempr=lson[tempr]; templ=lson[templ]; } else{ l=middle+1; memset(usemark,false,sizeof(usemark)); for(int i=right;i>0;i=i-lowbit(i)){ use[i]=rson[use[i]]; usemark[i]=true; } for(int i=left-1;i>0;i=i-lowbit(i)){ if(!usemark[i]){ use[i]=rson[use[i]]; } } tempr=rson[tempr]; templ=rson[templ]; k=k-cnt; } } return l; } int main(){ int t; int q; char op[10]; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&q); for(int i=1;i<=n;i++){ scanf("%d",&num[i]); newid[i]=num[i]; } m=n; for(int i=0;i<q;i++){ scanf("%s",op); if(op[0]=='Q'){ queryarray[i].type=0; scanf("%d%d%d",&queryarray[i].l,&queryarray[i].r,&queryarray[i].k); } else{ queryarray[i].type=1; scanf("%d%d",&queryarray[i].l,&queryarray[i].r); newid[++m]=queryarray[i].r; } } tot=0; lisanhua(); T[0]=build(1,m); for(int i=1;i<=n;i++){ T[i]=insert(T[i-1],numhash(num[i]),1); } for(int i=1;i<=n;i++){ S[i]=T[0]; } for(int i=0;i<q;i++){ /*for(int i=1;i<=n;i++){ printf("%d ",num[i]); } printf("\n");*/ if(queryarray[i].type==0){ printf("%d\n",newid[query(queryarray[i].l,queryarray[i].r,queryarray[i].k)]); } else if(queryarray[i].type==1){ modify(queryarray[i].l,numhash(num[queryarray[i].l]),-1); modify(queryarray[i].l,numhash(queryarray[i].r),1); num[queryarray[i].l]=queryarray[i].r; } } } return 0; }