1. 程式人生 > >Splay(區間翻轉) 模板

Splay(區間翻轉) 模板

iostream post tar clas spl sca .org while color

洛谷:P3391 【模板】文藝平衡樹(Splay)

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 using namespace std;
 5 const int MAXN=110000;
 6 int n,m,tp,root,CNT;
 7 int key[MAXN],lz[MAXN],fa[MAXN],sz[MAXN],val[MAXN],q[MAXN],Q[MAXN],ch[MAXN][2];
 8 void update(int k){ sz[k]=sz[ch[k][0
]]+sz[ch[k][1]]+1; } 9 void rotate(int x,int &y) 10 { 11 int old=fa[x],oldf=fa[old],op=ch[old][1]==x; 12 if(old==y) y=x; 13 else ch[oldf][ch[oldf][1]==old]=x; 14 fa[x]=oldf; 15 fa[ch[x][op^1]]=old; ch[old][op]=ch[x][op^1]; 16 fa[old]=x; ch[x][op^1]=old; 17 update(old); update(x);
18 } 19 void down(int x) 20 { 21 if(lz[x]) 22 { 23 lz[x]^=1; lz[ch[x][0]]^=1; lz[ch[x][1]]^=1; 24 swap(ch[x][0],ch[x][1]); 25 } 26 } 27 void splay(int x,int &y) 28 { 29 int now=x,old,oldf;Q[++tp]=now; 30 while(now!=y) Q[++tp]=fa[now] , now=fa[now]; 31 while
(tp--) down(Q[tp]); 32 while(x!=y) 33 { 34 old=fa[x],oldf=fa[old]; 35 if(old!=y){ 36 if((ch[old][0]==x)^(ch[oldf][0]==old)) rotate(x,y); 37 else rotate(old,y); 38 } 39 rotate(x,y); 40 } 41 } 42 void Build(int &k,int ll,int rr,int FA) 43 { 44 int mid=(ll+rr)/2; 45 k=++CNT; fa[k]=FA; key[k]=val[mid]; 46 if(mid>ll) Build(ch[k][0],ll,mid-1,k); 47 if(mid<rr) Build(ch[k][1],mid+1,rr,k); 48 update(k); 49 } 50 int findx(int x)//註意下放。 51 { 52 int now=root; 53 while(1) 54 { 55 down(now); 56 if(x<=sz[ch[now][0]]) now=ch[now][0]; 57 else 58 { 59 x-=sz[ch[now][0]]+1; 60 if(x==0) return now; 61 else now=ch[now][1]; 62 } 63 } 64 } 65 void rev(int L,int R) 66 { 67 int ll=findx(L-1),rr=findx(R+1); 68 splay(ll,root); 69 splay(rr,ch[root][1]); 70 lz[ch[ch[root][1]][0]]^=1; 71 } 72 void dfs(int u) 73 { 74 down(u); 75 if(ch[u][0]) dfs(ch[u][0]); 76 if(key[u]!=0&&key[u]!=n+1) printf("%d ",key[u]); 77 if(ch[u][1]) dfs(ch[u][1]); 78 } 79 int main() 80 { 81 scanf("%d%d",&n,&m); 82 for(int i=1;i<=n;i++)val[i]=i; 83 Build(root,0,n+1,0); 84 for(int i=1,L,R;i<=m;i++) 85 { 86 scanf("%d%d",&L,&R); 87 L++; R++; rev(L,R); 88 } 89 dfs(root); puts(""); 90 return 0; 91 }

Splay(區間翻轉) 模板