# BZOJ 4552 [Tjoi2016&Heoi2016]排序 线段树的分裂和合并

https://www.lydsy.com/JudgeOnline/problem.php?id=4552

https://blog.csdn.net/zawedx/article/details/51818475

  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;
29         if(zz)return zz;
30         if(mid<=k)return rn[lc];
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;
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){
84             //cout<<w<<' ';
87         }printf("\n");*/
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){
120         //cout<<w<<' ';
129 }