Title Description: https://www.luogu.org/problemnew/show/P3391
Analysis: Here we mainly talk about the view of the weights of the points on the splay. First of all, we find that the middle order traversal of a splay is always the same, so we think of using the middle order traversal of a splay to represent the position of the original array. So how to achieve it? We only need to take the position as the weight to build the tree at the beginning. To put it another way, building a tree by location is just to make the middle order of splay traverse orderly. So in fact, this splay still takes the number of the original array as the weight, only when the tree was first built, it changed the tree building method. Then some students may ask, isn't it not satisfied with the nature of splay left small right big after swap? I'm not satisfied. Some students may ask another question: how to ensure that r+1 can rotate to the right son of l-1? Isn't it not satisfied with the nature of splay? Note that the rotation operation of a splay has nothing to do with the weight of the point, it just has something to do with how the tree is built.
Attach code (origin is the original array):
#include<cstdio> #include<algorithm> using namespace std; const int MAXN=100005; int n,m; int root; struct Node{ int size,son[2],val,fa,tag; }node[MAXN]; int ndnum=0; int origin[MAXN]; int check(int x){ return x==node[node[x].fa].son[1]; } void update(int x){ node[x].size=node[node[x].son[0]].size+node[node[x].son[1]].size+1; } void rotate(int x){ int y=node[x].fa,z=node[y].fa,d=check(x),xx=node[x].son[d^1]; node[y].son[d]=xx;node[xx].fa=y; node[z].son[check(y)]=x;node[x].fa=z; node[x].son[d^1]=y;node[y].fa=x; update(y);update(x); } void splay(int x,int to=0){ while(node[x].fa!=to){ int y=node[x].fa,z=node[y].fa; if(z!=to){ if(check(x)==check(y)) rotate(y); else rotate(x); } rotate(x); } if(!to) root=x; } void insert(int x){ int cur=root,f=0; while(cur&&node[cur].val!=x){ f=cur; cur=node[cur].son[x>node[cur].val]; } cur=++ndnum; if(f) node[f].son[x>node[f].val]=cur; node[cur].size=1;node[cur].tag=0; node[cur].son[0]=node[cur].son[1]=0; node[cur].val=x;node[cur].fa=f; splay(cur); } void pushdown(int cur){ if(node[cur].tag){ node[node[cur].son[0]].tag^=1; node[node[cur].son[1]].tag^=1; node[cur].tag=0; swap(node[cur].son[0],node[cur].son[1]); } } int kth(int k){ int cur=root; while(1){ pushdown(cur); if(k<=node[node[cur].son[0]].size) cur=node[cur].son[0]; else{ k-=node[node[cur].son[0]].size+1; if(!k) return cur; cur=node[cur].son[1]; } } } void reserve(int l,int r){ l=kth(l-1);r=kth(r+1); splay(l);splay(r,l); node[node[node[root].son[1]].son[0]].tag^=1; } void write(int cur){ pushdown(cur); if(node[cur].son[0]) write(node[cur].son[0]); if(node[cur].val>1&&node[cur].val<n+2) printf("%d ",origin[node[cur].val-1]); if(node[cur].son[1]) write(node[cur].son[1]); } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&origin[i]); for(int i=1;i<=n+2;i++) insert(i); for(int i=1;i<=m;i++){ int l,r; scanf("%d%d",&l,&r); reserve(l+1,r+1); } write(root); return 0; }