bzoj3223Tyvj 1729 文艺平衡树

bzoj3223Tyvj 1729 文艺平衡树

题意:

一个数列,支持区间翻转操作。

题解:

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

posted @ 2016-07-24 20:02  YuanZiming  阅读(172)  评论(0编辑  收藏  举报