bzoj 3223 文艺平衡树
题目大意:
维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
思路:
splay 区间操作
%%%棒神
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 2139062143 10 #define ll long long 11 #define MAXN 100100 12 using namespace std; 13 inline int read() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 17 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 18 return x*f; 19 } 20 int n,m; 21 int rt,sz; 22 int ch[MAXN][2],f[MAXN],tag[MAXN],cnt[MAXN],val[MAXN],a[MAXN]; 23 int which(int x) {return x==ch[f[x]][1];} 24 void upd(int x) 25 { 26 if(!x) return ; 27 cnt[x]=1+cnt[ch[x][1]]+cnt[ch[x][0]]; 28 } 29 void pshd(int x) 30 { 31 if(x&&tag[x]) 32 { 33 tag[ch[x][0]]^=1,tag[ch[x][1]]^=1,tag[x]=0; 34 swap(ch[x][0],ch[x][1]); 35 } 36 } 37 void rotate(int x) 38 { 39 pshd(f[x]),pshd(x); 40 int fa=f[x],ff=f[fa],k=which(x); 41 ch[fa][k]=ch[x][k^1],f[ch[fa][k]]=fa,f[fa]=x,ch[x][k^1]=fa,f[x]=ff; 42 if(ff) ch[ff][ch[ff][1]==fa]=x; 43 upd(fa);upd(x); 44 } 45 void splay(int x,int g) 46 { 47 for(int fa;(fa=f[x])!=g;rotate(x)) 48 if(f[fa]!=g) rotate((which(x)==which(fa))?fa:x); 49 if(!g) rt=x; 50 } 51 int build(int l,int r,int fa) 52 { 53 if (l>r) return 0; 54 int mid=(l+r)>>1,pos=++sz; 55 val[pos]=a[mid],f[pos]=fa,tag[pos]=0; 56 int lc=build(l,mid-1,pos); 57 int rc=build(mid+1,r,pos); 58 ch[pos][0]=lc,ch[pos][1]=rc; 59 upd(pos); 60 return pos; 61 } 62 int find(int x) 63 { 64 int pos=rt; 65 while(1) 66 { 67 pshd(pos); 68 if(x<=cnt[ch[pos][0]]) pos=ch[pos][0]; 69 else 70 { 71 x-=cnt[ch[pos][0]]+1; 72 if(!x) return pos; 73 pos=ch[pos][1]; 74 } 75 } 76 } 77 void P(int pos) 78 { 79 pshd(pos); 80 if(ch[pos][0]) P(ch[pos][0]); 81 if(val[pos]!=-inf&&val[pos]!=inf) printf("%d ",val[pos]); 82 if(ch[pos][1]) P(ch[pos][1]); 83 } 84 int main() 85 { 86 n=read(),m=read(),a[1]=-inf,a[n+2]=inf;int x,y,z,b; 87 for(int i=1;i<=n;i++) a[i+1]=i; 88 rt=build(1,n+2,0); 89 while(m--) 90 { 91 x=read(),y=read(),z=find(x),b=find(y+2); 92 splay(z,0);splay(b,z); 93 tag[ch[ch[rt][1]][0]]^=1; 94 } 95 P(rt); 96 }