文艺平衡树[Splay]
题目
题解
Splay板子题
结果还调了很久的题,这就是搞文化课的副作用
显然维护数组下标,使得Splay的中序遍历始终为当前数列
值得注意:
旋转时始终要记得更新节点
注意更新root节点
每次写都忘.jpg
#include<bits/stdc++.h> using namespace std; const int MAXN = 100000 + 10; inline int read() { int f=1,x=0; char ch; do { ch=getchar(); if(ch=='-') f=-1; }while(ch<'0'||ch>'9'); do { x=(x<<3)+(x<<1)+ch-'0'; ch=getchar(); }while(ch>='0'&&ch<='9'); return f*x; } struct Splay { int ch[MAXN][2]; int idx; int val[MAXN]; int sz[MAXN]; int fa[MAXN],root; int tag[MAXN]; inline int chk(int x) { return x==ch[fa[x]][1]; } inline void pushup(int x) { sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1; } inline void pushdown(int x) { if(!tag[x]) return; tag[ch[x][0]]^=1; tag[ch[x][1]]^=1; swap(ch[x][0],ch[x][1]); tag[x]=0; } inline void rotate(int x) { int f=fa[x],gf=fa[f]; int k=chk(x); ch[gf][chk(f)]=x; fa[x]=gf; ch[f][k]=ch[x][k^1];fa[ch[x][k^1]]=f; ch[x][k^1]=f; fa[f]=x; pushup(f);pushup(x); } inline void splay(int x,int goal) { while(fa[x]!=goal) { int f=fa[x],gf=fa[f]; if(gf!=goal) { if(chk(x)==chk(f)) rotate(f); else rotate(x); } rotate(x); } if(!goal) root=x; } inline int kth(int k) { int cur=root; while(1) { pushdown(cur); if(sz[ch[cur][0]]>=k) cur=ch[cur][0]; else if(sz[ch[cur][0]]+1==k) return cur; else k-=sz[ch[cur][0]]+1,cur=ch[cur][1]; } } inline void insert(int x) { int cur=root,f=0; while(cur&&val[cur]!=x) { f=cur; if(val[cur]>x) cur=ch[cur][0]; else cur=ch[cur][1]; } cur=++idx; if(f) ch[f][val[f]<x]=x; sz[cur]=1; ch[cur][0]=ch[cur][1]=0; val[cur]=x;fa[cur]=f; if(!root) root=cur; splay(cur,0); } }tree; int n,m; inline void update(int l,int r) { l=tree.kth(l); r=tree.kth(r+2); tree.splay(l,0); tree.splay(r,l); tree.tag[tree.ch[tree.ch[l][1]][0]]^=1; } inline void dfs(int cur) { tree.pushdown(cur); if(tree.ch[cur][0]) dfs(tree.ch[cur][0]); if(tree.val[cur]>1&&tree.val[cur]<n+2) printf("%d ",tree.val[cur]-1); if(tree.ch[cur][1]) dfs(tree.ch[cur][1]); return; } int main() { n=read(),m=read(); for(int i=1;i<=n+2;i++) { tree.insert(i); } for(int i=1;i<=m;i++) { int l=read(),r=read(); update(l,r); } dfs(tree.root); }