题意:
一个数列,支持区间翻转操作。
题解:
splay裸题。注意涉及到区间操作的一般用splay不用treap。
代码:
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #define inc(i,j,k) for(int i=j;i<=k;i++) 5 #define fa(x) nds[x].fa 6 #define ch(x,y) nds[x].ch[y] 7 #define tg(x) nds[x].tg 8 #define v(x) nds[x].v 9 #define sz(x) nds[x].sz 10 using namespace std; 11 12 struct nd{int fa,ch[2],v,sz,tg;}; 13 nd nds[200000]; int size,root,n,m; bool first; 14 void pushdown(int x){ 15 if(! x)return; if(tg(x)){ 16 if(ch(x,0)&&ch(x,1))swap(ch(x,0),ch(x,1)),tg(ch(x,0))^=1,tg(ch(x,1))^=1;else 17 if(ch(x,0))ch(x,1)=ch(x,0),ch(x,0)=0,tg(ch(x,1))^=1;else ch(x,0)=ch(x,1),ch(x,1)=0,tg(ch(x,0))^=1; 18 tg(x)^=1; 19 } 20 } 21 void update(int x){if(! x)return; sz(x)=sz(ch(x,0))+sz(ch(x,1))+1;} 22 void rotate(int x){ 23 if(x==0||fa(x)==0)return; 24 int a1=fa(x),a2=fa(a1); bool a3=(x==ch(a1,1)),a4=(a1==ch(a2,1)); 25 if(a2)ch(a2,a4)=x; if(ch(x,!a3))fa(ch(x,!a3))=a1; ch(a1,a3)=ch(x,!a3); ch(x,!a3)=a1; 26 fa(x)=a2; fa(a1)=x; update(a1); update(x); if(a2)update(a2); 27 } 28 void splay(int x,int y){ 29 if(x==0||y==0)return; int z=fa(y); if(y==root)root=x; 30 while(fa(x)!=z){ 31 if(fa(fa(x))!=z){ 32 if((x==ch(fa(x),1))^(fa(x)==ch(fa(fa(x)),1)))rotate(x);else rotate(fa(x)); 33 } 34 rotate(x); 35 } 36 } 37 int build(int l,int r){ 38 if(l>r)return 0; 39 ++size; int ff=size; int m=(l+r)>>1; ch(ff,0)=build(l,m-1); ch(ff,1)=build(m+1,r); 40 if(ch(ff,0))fa(ch(ff,0))=ff; if(ch(ff,1))fa(ch(ff,1))=ff; 41 v(ff)=m; tg(ff)=0; update(ff); return ff; 42 } 43 int find(int p){ 44 int x=root; while(1){ 45 if(x==0)return 0; pushdown(x); 46 int a1=sz(ch(x,0)); if(a1+1==p)return x; 47 if(a1+1<p)p-=(a1+1),x=ch(x,1);else x=ch(x,0); 48 } 49 } 50 void rever(int l,int r){ 51 int a1=find(l-1),a2=find(r+1); splay(a2,root); 52 if(l>1)splay(a1,ch(a2,0)),tg(ch(a1,1))^=1;else tg(ch(a2,0))=1; 53 } 54 void print(int x){ 55 if(x==0)return; pushdown(x); 56 print(ch(x,0)); 57 if(v(x)!=n+1) 58 if(!first)printf("%d",v(x)),first=1;else printf(" %d",v(x)); 59 print(ch(x,1)); 60 } 61 int main(){ 62 //freopen("test.txt","r",stdin); 63 scanf("%d%d",&n,&m); size=0; root=build(1,n+1); 64 inc(i,1,m){ 65 int a,b; scanf("%d%d",&a,&b); rever(a,b); 66 } 67 first=0; print(root); 68 return 0; 69 }
20160418