水题。。。貌似理解splay怎么维护数列了。。。
每个点维护一个size,它的位置就是它的size,区间翻转的话可以打标记,find的时候push_down,交换左右子树。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #define N 100005 6 #define lc(x) ch[x][0] 7 #define rc(x) ch[x][1] 8 using namespace std; 9 int cnt; 10 int k[N]; 11 int size[N]; 12 int lazy[N]; 13 int ch[N][2]; 14 int dai[N];int fa[N]; 15 int n,m;int root; 16 void push_up(int x) 17 { 18 size[x]=size[ch[x][0]]+size[ch[x][1]]+1; 19 return ; 20 } 21 void rotate(int p) 22 { 23 int q=fa[p],y=fa[q],x=(ch[q][1]==p); 24 ch[q][x]=ch[p][x^1];fa[ch[p][x^1]]=q; 25 ch[p][x^1]=q;fa[q]=p;fa[p]=y; 26 if(y) 27 { 28 if(q==ch[y][0])ch[y][0]=p;else ch[y][1]=p; 29 } 30 push_up(q);push_up(p); 31 return ; 32 } 33 void splay(int x,int pos) 34 { 35 for(int y;y=fa[x];rotate(x)) 36 { 37 if(y==pos)break; 38 if(fa[y]!=pos) 39 { 40 if((ch[fa[y]][0]==y&&ch[y][0]==x)||(ch[fa[y]][1]==y&&ch[y][1]==x))rotate(y); 41 else rotate(x); 42 } 43 } 44 if(!pos)root=x; 45 } 46 void push_down(int x) 47 { 48 if(lazy[x]) 49 { 50 lazy[x]=0; 51 lazy[ch[x][0]]^=1;lazy[ch[x][1]]^=1; 52 swap(ch[x][0],ch[x][1]); 53 } 54 } 55 int find(int k,int rank) 56 { 57 push_down(k); 58 int l=ch[k][0];int r=ch[k][1]; 59 if(size[l]+1==rank)return k; 60 else if(size[l]>=rank)return find(ch[k][0],rank); 61 else return find(ch[k][1],rank-size[l]-1); 62 } 63 void dfs(int x) 64 { 65 push_down(x); 66 if(ch[x][0])dfs(ch[x][0]); 67 if(k[x]!=0&&k[x]!=n+1)printf("%d ",k[x]); 68 if(ch[x][1])dfs(ch[x][1]); 69 } 70 int main() 71 { 72 scanf("%d%d",&n,&m); 73 cnt=n+2;root=1; 74 for(int i=0;i<=n+1;i++) 75 { 76 ch[i+1][1]=i+2; 77 fa[i+2]=i+1; 78 k[i+1]=i; 79 size[i+1]=n+2-i; 80 }ch[n+2][1]=0; 81 for(int i=1;i<=m;i++) 82 { 83 int t1,t2; 84 scanf("%d%d",&t1,&t2); 85 int x1=find(root,t1);int x2=find(root,t2+2); 86 splay(x1,0);splay(x2,x1); 87 lazy[ch[x2][0]]^=1; 88 } 89 dfs(root); 90 return 0; 91 } 92 /* 93 5 1 94 1 4 95 */