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 }
View Code

 

posted @ 2018-06-20 08:06  鲸头鹳  阅读(145)  评论(0编辑  收藏  举报