洛谷P3960 列队(Splay)
感觉自己好久不打数据结构已经完全不会了orz……
据说正解树状数组?然而并不会
首先考虑一下每一次操作,就是把一个人从这一行中取出并放到行的最后,再从最后一列取出放到列的最后
那么这两种操作其实可以看做同一个类型,都是把某一个数取出并放到最后
那么这个可以用splay来搞,用splay维护区间,然后每一次找第k个相当于找第k大,然后删除之后在末尾插入
然后如果直接开空间怕是要炸……那只能缩点,等做到这个点的时候再把它split出来……
然后……看代码好了……
1 //minamoto 2 #include<cstdio> 3 #include<iostream> 4 #define ll long long 5 #define inf 0x3f3f3f3f 6 using namespace std; 7 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 8 char buf[1<<21],*p1=buf,*p2=buf; 9 inline int read(){ 10 #define num ch-'0' 11 char ch;bool flag=0;int res; 12 while(!isdigit(ch=getc())) 13 (ch=='-')&&(flag=true); 14 for(res=num;isdigit(ch=getc());res=res*10+num); 15 (flag)&&(res=-res); 16 #undef num 17 return res; 18 } 19 char sr[1<<21],z[20];int C=-1,Z; 20 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;} 21 inline void print(ll x){ 22 if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x; 23 while(z[++Z]=x%10+48,x/=10); 24 while(sr[++C]=z[Z],--Z);sr[++C]='\n'; 25 } 26 const int N=1e7+5,maxn=3e5+5; 27 int n,m,q,x,y;ll t,u; 28 int fa[N],ch[N][2],tot;ll L[N],R[N],sz[N]; 29 struct Splay{ 30 #define ls ch[x][0] 31 #define rs ch[x][1] 32 int rt; 33 inline int newnode(ll l,ll r){ 34 L[++tot]=l,R[tot]=r,sz[tot]=r-l+1;return tot; 35 } 36 inline void upd(int x){ 37 sz[x]=sz[ls]+sz[rs]+R[x]-L[x]+1; 38 } 39 void rotate(int x){ 40 int y=fa[x],z=fa[y],d=ch[y][1]==x; 41 ch[z][ch[z][1]==y]=x; 42 fa[x]=z,fa[y]=x,fa[ch[x][d^1]]=y,ch[y][d]=ch[x][d^1],ch[x][d^1]=y,upd(y); 43 } 44 void splay(int x){ 45 for(int y=fa[x],z=fa[y];fa[x];y=fa[x],z=fa[y]){ 46 if(fa[y]) 47 ((ch[y][1]==x)^(ch[z][1]==y))?rotate(x):rotate(y); 48 rotate(x); 49 } 50 upd(x),rt=x; 51 } 52 inline void ins(ll v){ 53 int x=rt; 54 while(rs) x=rs; 55 newnode(v,v),fa[tot]=x,rs=tot,splay(tot); 56 } 57 ll split(int x,ll k){ 58 ll s=L[x],t=R[x]; 59 if(k!=s&&k!=t){ 60 if(s+1<t){ 61 int a=newnode(k+1,t);R[x]=k-1; 62 ch[a][1]=ch[x][1],ch[x][1]=a,fa[a]=x,upd(a),upd(x); 63 splay(a); 64 }else{++L[x],splay(x);} 65 }else{ 66 k==t?--t:++s; 67 L[x]=s,R[x]=t,sz[x]=t-s+1,splay(x); 68 } 69 return k; 70 } 71 ll rk(int k){ 72 int x=rt; 73 while(true){ 74 if(sz[ls]>=k) x=ls; 75 else{ 76 k-=sz[ls]; 77 if(k<=R[x]-L[x]+1) return split(x,k+L[x]-1); 78 k-=R[x]-L[x]+1,x=rs; 79 } 80 } 81 } 82 inline void init(ll l,ll r){rt=newnode(l,r);} 83 int build(int l,int r,int f){ 84 if(l>r) return 0; 85 int mid=(l+r)>>1,x=newnode(1ll*m*mid,1ll*m*mid); 86 fa[x]=f; 87 ls=build(l,mid-1,x); 88 rs=build(mid+1,r,x); 89 return upd(x),x; 90 } 91 }T[maxn]; 92 int main(){ 93 // freopen("testdata.in","r",stdin); 94 n=read(),m=read(),q=read(); 95 for(int i=1;i<=n;++i) T[i].init(1ll*(i-1)*m+1,1ll*i*m-1); 96 T[0].rt=T[0].build(1,n,0); 97 while(q--){ 98 x=read(),y=read(); 99 if(y==m){ 100 print(u=T[0].rk(x)),T[0].ins(u); 101 }else{ 102 print(u=T[x].rk(y)); 103 t=T[0].rk(x); 104 T[x].ins(t),T[0].ins(u); 105 } 106 } 107 Ot(); 108 return 0; 109 }
深深地明白自己的弱小