【luogu P3391】文艺平衡树
要在Splay中修改区间的话,可以先查找size值为l与r+2的两个节点,将一个旋转到根,另一个旋转到根的右儿子上,则要修改的区间就是根的右孩子的左子树
然后直接打翻转标记即可,翻转标记类似于线段树的懒标记,查第k大的时候pushdown,pushdown就是把左儿子,右儿子的位置交换
#include<bits/stdc++.h> #define N 100005 using namespace std; int n,m,tot,root; struct node { int ch[2],val,size,same,father,mark; }tree[N]; inline void pushup(int now) { tree[now].size=tree[tree[now].ch[0]].size+1+tree[tree[now].ch[1]].size; } inline void pushdown(int now) { if(tree[now].mark) { tree[tree[now].ch[0]].mark^=1; tree[tree[now].ch[1]].mark^=1; tree[now].mark=0; swap(tree[now].ch[0],tree[now].ch[1]); } } inline void rotate(int x) { int y=tree[x].father; int z=tree[y].father; int k=(tree[y].ch[1]==x);//x是y的什么儿子 tree[z].ch[tree[z].ch[1]==y]=x; tree[x].father=z; tree[y].ch[k]=tree[x].ch[k^1]; tree[tree[x].ch[k^1]].father=y; tree[x].ch[k^1]=y; tree[y].father=x; pushup(y);pushup(x); } void splay(int x,int goal) { while(tree[x].father!=goal) { int y=tree[x].father; int z=tree[y].father; if(z!=goal) (tree[y].ch[0]==x)^(tree[z].ch[0]==y)?rotate(x):rotate(y); rotate(x); } if(!goal) root=x; } inline void insert(int x) { int now=root,ff=0; while(now) { ff=now; now=tree[now].ch[tree[now].val<x]; } now=++tot; tree[now].father=ff; tree[ff].ch[x>tree[ff].val]=now; tree[now].val=x; tree[now].size=1; splay(now,0); } inline int kth(int x) { int now=root; while(19260817) { pushdown(now); if(tree[tree[now].ch[0]].size>=x) now=tree[now].ch[0]; else if(x>tree[tree[now].ch[0]].size+1) { x-=tree[tree[now].ch[0]].size+1; now=tree[now].ch[1]; } else return tree[now].val; } } void write(int now) { pushdown(now); if(tree[now].ch[0]) write(tree[now].ch[0]); if(tree[now].val>1&&tree[now].val<n+2) cout<<tree[now].val-1<<" "; if(tree[now].ch[1]) write(tree[now].ch[1]); } int main() { ios::sync_with_stdio(false); cin.tie(NULL);cout.tie(NULL); cin>>n>>m; for(int i=1;i<=n+2;i++) insert(i);//1,n+2是虚拟节点 while(m--) { int l,r,kl,kr; cin>>l>>r; kl=kth(l); kr=kth(r+2); splay(kl,0); splay(kr,kl); tree[tree[tree[root].ch[1]].ch[0]].mark^=1; } write(root); return 0; }
QQ40523591~欢迎一起学习交流~