OrzOrzOrz
OTZOTZOTZ
%%%%%%%%%%%%
长跪不起
http://www.cnblogs.com/zig-zag/archive/2013/04/18/3027707.html
就在本蒟蒻还在为树套树套树套树怎么写而发愁时(反正就是不会写+懒得写),突然发现了这么个利器。
哈哈哈哈哈哈哈哈哈哈哈哈哈。
以后完全不用写什么高端的数据结构了。
统统离线好了(什么强制在线?不做)。
顺便做了下ZOJ2112和POJ2104(一开始狂TLE发现数组开小了,竟然没RE。。。)
一个是动态区间第K大,一个是静态区间第K大。
全都BIT+整体二分,短小精悍。
ZOJ2112:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=50000+5; const int M=10000+5; const int inf=1e9; struct Query{ int x,y,k,tp,id,cur; }q[N+M*2],q1[N+M*2],q2[N+M*2]; int a[N],ans[M],tmp[N+M*2],c[N]; int n,m,cnt,num; inline int lowbit(int x){return x&-x;} void add(int x,int v){ for(;x<=n;x+=lowbit(x))c[x]+=v; } int sum(int x){ int ret=0; for(;x>0;x-=lowbit(x))ret+=c[x]; return ret; } void divide(int head,int tail,int l,int r){ if(head>tail)return; if(l==r){ for(int i=head;i<=tail;i++) if(q[i].tp==3)ans[q[i].id]=l; return; } int mid=l+r>>1; for(int i=head;i<=tail;i++) if(q[i].tp==1&&q[i].y<=mid) add(q[i].x,1); else if(q[i].tp==2&&q[i].y<=mid) add(q[i].x,-1); else if(q[i].tp==3) tmp[i]=sum(q[i].y)-sum(q[i].x-1); for(int i=head;i<=tail;i++) if(q[i].tp==1&&q[i].y<=mid) add(q[i].x,-1); else if(q[i].tp==2&&q[i].y<=mid) add(q[i].x,1); int l1=0,l2=0; for(int i=head;i<=tail;i++) if(q[i].tp==3){ if(q[i].cur+tmp[i]>q[i].k-1)q1[++l1]=q[i]; else q[i].cur+=tmp[i],q2[++l2]=q[i]; }else{ if(q[i].y<=mid)q1[++l1]=q[i]; else q2[++l2]=q[i]; } for(int i=1;i<=l1;i++)q[head+i-1]=q1[i]; for(int i=1;i<=l2;i++)q[head+i-1+l1]=q2[i]; divide(head,head+l1-1,l,mid); divide(head+l1,tail,mid+1,r); } int main(){ int X;scanf("%d",&X); while(X--){ scanf("%d%d",&n,&m); cnt=0;num=0; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); q[++cnt].x=i;q[cnt].y=a[i];q[cnt].tp=1; } int x,y,k;char opt[10]; for(int i=1;i<=m;i++){ scanf("%s",opt); if(opt[0]=='Q'){ scanf("%d%d%d",&x,&y,&k); q[++cnt].x=x;q[cnt].y=y;q[cnt].k=k;q[cnt].cur=0;q[cnt].id=++num;q[cnt].tp=3; }else{ scanf("%d%d",&x,&y); q[++cnt].x=x;q[cnt].y=a[x];q[cnt].tp=2; q[++cnt].x=x;q[cnt].y=y;q[cnt].tp=1; a[x]=y; } } divide(1,cnt,0,inf); for(int i=1;i<=num;i++) printf("%d\n",ans[i]); } return 0; }POJ2104:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int inf=1e9; const int N=100000+5; const int M=5000+5; struct Query{ int x,y,k,id,tp,cur; }q[N+M],q1[N+M],q2[N+M]; int ans[M],tmp[N+M],d[N]; int n,m,cnt; inline int lowbit(int x){return x&-x;} void add(int x,int v){ for(;x<=n;x+=lowbit(x))d[x]+=v; } int sum(int x){ int ret=0; for(;x>0;x-=lowbit(x))ret+=d[x]; return ret; } void divide(int head,int tail,int l,int r){ if(head>tail)return; if(l==r){ for(int i=head;i<=tail;i++) if(q[i].tp==2)ans[q[i].id]=l; return; } int mid=l+(r-l)/2; for(int i=head;i<=tail;i++) if(q[i].tp==1&&q[i].y<=mid)add(q[i].x,1); else if(q[i].tp==2)tmp[i]=sum(q[i].y)-sum(q[i].x-1); for(int i=head;i<=tail;i++) if(q[i].tp==1&&q[i].y<=mid)add(q[i].x,-1); int l1=0,l2=0; for(int i=head;i<=tail;i++) if(q[i].tp==2){ if(q[i].cur+tmp[i]>q[i].k-1)q1[++l1]=q[i]; else q[i].cur+=tmp[i],q2[++l2]=q[i]; }else{ if(q[i].y<=mid)q1[++l1]=q[i]; else q2[++l2]=q[i]; } for(int i=1;i<=l1;i++)q[head+i-1]=q1[i]; for(int i=1;i<=l2;i++)q[head+i+l1-1]=q2[i]; divide(head,head+l1-1,l,mid); divide(head+l1,tail,mid+1,r); } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ q[++cnt].x=i;scanf("%d",&q[cnt].y); q[cnt].tp=1; } for(int i=1;i<=m;i++){ q[++cnt].id=i; scanf("%d%d%d",&q[cnt].x,&q[cnt].y,&q[cnt].k); q[cnt].tp=2; } divide(1,cnt,-inf,inf); for(int i=1;i<=m;i++) printf("%d\n",ans[i]); return 0; }