BZOJ 4552 [Tjoi2016&Heoi2016]排序 线段树的分裂和合并
https://www.lydsy.com/JudgeOnline/problem.php?id=4552
https://blog.csdn.net/zawedx/article/details/51818475
区间排序,这道题需要写两个线段树还要维护一个链表,有些细节,对我目前的代码能力来说有点算是码农题,但是理解思路之后调试起来出乎意料地简单。
这个写法的复杂度据说是nlogn的,我也不是很会算,反正能过就行(bushi)。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 #define LL long long 9 #define lc x*2 10 #define rc x*2+1 11 #define mid (l+r)/2 12 const int maxn=100010; 13 const int maxm=2000010; 14 int n,m; 15 struct sgtree{ 16 int rn[maxm]; 17 void updata(int x){rn[x]=(rn[rc]?rn[rc]:rn[lc]);} 18 void ins(int x,int l,int r,int k,int v){ 19 if(l==r){rn[x]=v;return;} 20 if(k>mid)ins(rc,mid+1,r,k,v); 21 else ins(lc,l,mid,k,v); 22 updata(x); 23 } 24 int ask(int x,int l,int r,int k){ 25 if(!rn[x])return 0; 26 if(l==r)return rn[x]; 27 int zz=0; 28 if(mid<k)zz=ask(rc,mid+1,r,k); 29 if(zz)return zz; 30 if(mid<=k)return rn[lc]; 31 else return ask(lc,l,mid,k); 32 } 33 }e; 34 struct nod{ int l,r,tp,nxt; }c[maxm]; 35 struct node{ int l,r,sum; }t[maxm]; 36 queue<int>q; 37 inline int newp(){ 38 int z=q.front();q.pop(); 39 return z; 40 } 41 inline void delp(int x){ 42 q.push(x);t[x]=t[0]; 43 } 44 void build(int x,int l,int r,int k){ 45 t[x].sum=1; 46 if(l==r)return; 47 if(k>mid)build(t[x].r=newp(),mid+1,r,k); 48 else build(t[x].l=newp(),l,mid,k); 49 } 50 int mmerg(int x,int y){ 51 if((!x)||(!y))return x+y; 52 t[x].l=mmerg(t[x].l,t[y].l); 53 t[x].r=mmerg(t[x].r,t[y].r); 54 t[x].sum=t[x].sum+t[y].sum; 55 delp(y); return x; 56 } 57 void mspli(int x,int y,int k){ 58 int z=t[t[x].l].sum; 59 if(z<k)mspli(t[x].r,t[y].r=newp(),k-z);else swap(t[x].r,t[y].r); 60 if(z>k)mspli(t[x].l,t[y].l=newp(),k); 61 t[y].sum=t[x].sum-k; 62 t[x].sum=k; 63 } 64 int mask(int x,int l,int r,int k){ 65 if(l==r)return l; 66 int z=t[t[x].l].sum; 67 if(k>z)return mask(t[x].r,mid+1,r,k-z); 68 else return mask(t[x].l,l,mid,k); 69 } 70 int main(){ 71 int x,v,op,l,r; 72 for(int i=1;i<=maxm-10;++i)q.push(i); 73 scanf("%d%d",&n,&m); 74 for(int i=1,las=maxm-5;i<=n;++i,las=x){ 75 scanf("%d",&v); 76 c[las].nxt=x=newp(); 77 c[x]=(nod){i,i,0,0}; 78 e.ins(1,1,n,i,x);build(x,1,n,v); 79 } 80 for(int i=1;i<=m;++i){ 81 scanf("%d%d%d",&op,&l,&r); 82 /*for(x=1;x<=n;++x){ 83 int w=e.ask(1,1,n,x); 84 //cout<<w<<' '; 85 if(c[w].tp)printf("%d ",mask(w,1,n,c[w].r-x+1)); 86 else printf("%d ",mask(w,1,n,x-c[w].l+1)); 87 }printf("\n");*/ 88 int lef=e.ask(1,1,n,l),rig,now,nxt; 89 if(l==c[lef].l){ 90 rig=newp(); 91 swap(t[rig],t[lef]); swap(c[rig],c[lef]); 92 c[now=lef]=(nod){l,r,op,rig}; 93 } 94 else{ 95 c[now=newp()]=(nod){l,r,op,rig=newp()}; 96 if(!c[lef].tp) mspli(lef,rig,l-c[lef].l); 97 else {mspli(lef,rig,c[lef].r-l+1);swap(t[lef],t[rig]);} 98 c[rig]=c[lef];c[rig].l=l; 99 c[lef].r=l-1;c[lef].nxt=now; 100 } 101 for(nxt=rig;nxt&&r>=c[nxt].r;){ 102 //cout<<t[nxt].sum<<endl; 103 mmerg(now,nxt);e.ins(1,1,n,c[nxt].l,0); 104 int qq=nxt;nxt=c[nxt].nxt;c[qq]=c[0]; 105 } 106 c[now].nxt=nxt; 107 if(nxt!=0&&c[nxt].l<=r){ 108 e.ins(1,1,n,c[nxt].l,0); 109 int zz=newp(); 110 if(!c[nxt].tp) {mspli(nxt,zz,r-c[nxt].l+1);swap(t[nxt],t[zz]);} 111 else mspli(nxt,zz,c[nxt].r-r); 112 mmerg(now,zz); 113 c[nxt].l=r+1; 114 e.ins(1,1,n,r+1,nxt); 115 } 116 e.ins(1,1,n,l,now); 117 } 118 /*for(x=1;x<=n;++x){ 119 int w=e.ask(1,1,n,x); 120 //cout<<w<<' '; 121 if(c[w].tp)printf("%d ",mask(w,1,n,c[w].r-x+1)); 122 else printf("%d ",mask(w,1,n,x-c[w].l+1)); 123 }printf("\n");*/ 124 scanf("%d",&x); 125 int w=e.ask(1,1,n,x); 126 if(c[w].tp)printf("%d\n",mask(w,1,n,c[w].r-x+1)); 127 else printf("%d\n",mask(w,1,n,x-c[w].l+1)); 128 return 0; 129 }