P3391 【模板】文艺平衡树 splay解法
P3391 【模板】文艺平衡树
splay解法1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | #include <bits/stdc++.h> using namespace std; const int N = 100005; int ch[N][2], par[N], val[N], cnt[N], size[N], rev[N], root, ncnt; int n, m, x, y; void output( int x); bool chk( int x) { return ch[par[x]][1] == x; } void pushup( int x) { size[x] = size[ch[x][0]] + size[ch[x][1]] + cnt[x]; } void pushdown( int x) { if (rev[x]) { swap(ch[x][0], ch[x][1]); rev[ch[x][0]] ^= 1; rev[ch[x][1]] ^= 1; rev[x] = 0; } } void rotate( int x) { int y = par[x], z = par[y], k = chk(x), w = ch[x][k^1]; ch[y][k] = w; par[w] = y; ch[z][chk(y)] = x; par[x] = z; ch[x][k^1] = y; par[y] = x; pushup(y); pushup(x); } void splay( int x, int goal = 0) { while (par[x] != goal) { int y = par[x], z = par[y]; if (z != goal) { if (chk(x) == chk(y)) rotate(y); else rotate(x); } rotate(x); } if (!goal) root = x; } void insert( int x) { int cur = root, p = 0; while (cur && val[cur] != x) { p = cur; cur = ch[cur][x > val[cur]]; } if (cur) { cnt[cur]++; } else { cur = ++ncnt; if (p) ch[p][x > val[p]] = cur; ch[cur][0] = ch[cur][1] = 0; par[cur] = p; val[cur] = x; cnt[cur] = size[cur] = 1; } splay(cur); } void find( int x) { int cur = root; while (ch[cur][x > val[cur]] && val[cur] != x) { cur = ch[cur][x > val[cur]]; } splay(cur); } int kth( int k) { int cur = root; while (1) { pushdown(cur); if (ch[cur][0] && k <= size[ch[cur][0]]) { cur = ch[cur][0]; } else if (k > size[ch[cur][0]] + cnt[cur]) { k -= size[ch[cur][0]] + cnt[cur]; cur = ch[cur][1]; } else { splay(cur); return cur; } } } void reverse( int l, int r) { int x = kth(l), y = kth(r+2); splay(x); splay(y, x); rev[ch[y][0]] ^= 1; } void output( int x) { pushdown(x); if (ch[x][0]) output(ch[x][0]); if (val[x] && val[x] <= n) printf( "%d " , val[x]); if (ch[x][1]) output(ch[x][1]); } int main() { scanf( "%d%d" , &n, &m); for ( int i = 0; i <= n+1; i++) insert(i); while (m--) { scanf( "%d%d" , &x, &y); reverse(x, y); } output(root); } |
splay解法2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; const int Maxn=1000007; const int inf=1e9; int f[Maxn],cnt[Maxn],ch[Maxn][2],size[Maxn],key[Maxn],tag[Maxn],sz,rt; int n,m,x,y,data[Maxn]; bool get ( int x) { return ch[f[x]][1]==x; } void pushup( int x) { size[x]=size[ch[x][0]]+size[ch[x][1]]+1; } void pushdown( int x) { if (x&&tag[x]) { tag[ch[x][0]]^=1; tag[ch[x][1]]^=1; swap(ch[x][0],ch[x][1]); tag[x]=0; } } void rotate( int x) { int old=f[x],oldf=f[old],which= get (x); pushdown(old);pushdown(x); ch[old][which]=ch[x][which^1];f[ch[old][which]]=old; ch[x][which^1]=old;f[old]=x; f[x]=oldf; if (oldf) ch[oldf][ch[oldf][1]==old]=x; pushup(old);pushup(x); } void splay( int x, int goat) { for ( int fa;(fa=f[x])!=goat;rotate(x)) { /* if (f[fa]!=goat) { rotate((get(x)==get(fa))?fa:x); } */ } if (!goat) rt=x; } int bulid_tree( int fa, int l, int r) { if (l>r) return 0; int mid=(l+r)>>1; int now=++sz; key[now]=data[mid];f[now]=fa;tag[now]=0; ch[now][0]=bulid_tree(now,l,mid-1); ch[now][1]=bulid_tree(now,mid+1,r); pushup(now); return now; } int rnk( int x) { int now=rt; while (1) { pushdown(now); if (x<=size[ch[now][0]]) now=ch[now][0]; else { x-=size[ch[now][0]]+1; if (!x) return now; now=ch[now][1]; } } } void turn( int l, int r) { l=rnk(l); r=rnk(r+2); splay(l,0); splay(r,l); pushdown(rt); tag[ch[ch[rt][1]][0]]^=1; } void write( int now) { pushdown(now); if (ch[now][0]) write(ch[now][0]); if (key[now]!=-inf&&key[now]!=inf) cout<<key[now]<< " " ; if (key[ch[now][1]]) write(ch[now][1]); } int main() { cin>>n>>m; for ( int i=1;i<=n;i++) data[i+1]=i; data[1]=-inf;data[n+2]=inf; rt=bulid_tree(0,1,n+2); for ( int i=1;i<=m;i++) { cin>>x>>y; turn(x,y); } write(rt); return 0; } |
splay解法3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; const int Maxn=1000007; const int inf=1e9; int f[Maxn],cnt[Maxn],ch[Maxn][2],size[Maxn],key[Maxn],tag[Maxn],sz,rt; int n,m,x,y,data[Maxn]; bool get ( int x) { return ch[f[x]][1]==x; } void pushup( int x) { size[x]=size[ch[x][0]]+size[ch[x][1]]+1; } void pushdown( int x) { if (x&&tag[x]) { tag[ch[x][0]]^=1; tag[ch[x][1]]^=1; swap(ch[x][0],ch[x][1]); tag[x]=0; } } void rotate( int x) { int old=f[x],oldf=f[old],which= get (x); pushdown(old);pushdown(x); ch[old][which]=ch[x][which^1];f[ch[old][which]]=old; ch[x][which^1]=old;f[old]=x; f[x]=oldf; if (oldf) ch[oldf][ch[oldf][1]==old]=x; pushup(old);pushup(x); } void splay( int x, int goat) { for ( int fa;(fa=f[x])!=goat;rotate(x)) { if (f[fa]!=goat) { rotate(( get (x)== get (fa))?fa:x); } } if (!goat) rt=x; } int bulid_tree( int fa, int l, int r) { if (l>r) return 0; int mid=(l+r)>>1; int now=++sz; key[now]=data[mid];f[now]=fa;tag[now]=0; ch[now][0]=bulid_tree(now,l,mid-1); ch[now][1]=bulid_tree(now,mid+1,r); pushup(now); return now; } int rnk( int x) { int now=rt; while (1) { pushdown(now); if (x<=size[ch[now][0]]) now=ch[now][0]; else { x-=size[ch[now][0]]+1; if (!x) return now; now=ch[now][1]; } } } void turn( int l, int r) { l=rnk(l); r=rnk(r+2); splay(l,0); splay(r,l); pushdown(rt); tag[ch[ch[rt][1]][0]]^=1; } void write( int now) { pushdown(now); if (ch[now][0]) write(ch[now][0]); if (key[now]!=-inf&&key[now]!=inf) cout<<key[now]<< " " ; if (key[ch[now][1]]) write(ch[now][1]); } int main() { cin>>n>>m; for ( int i=1;i<=n;i++) data[i+1]=i; data[1]=-inf;data[n+2]=inf; rt=bulid_tree(0,1,n+2); for ( int i=1;i<=m;i++) { cin>>x>>y; turn(x,y); } write(rt); return 0; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通