文艺平衡树
Posted shatianming
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文艺平衡树相关的知识,希望对你有一定的参考价值。
#include<bits/stdc++.h> #define MAXN 300005 using namespace std; int n,m,a,b; struct Splay{ int num[MAXN],ch[MAXN][2],sz[MAXN],f[MAXN],cnt[MAXN],rt,tot,tag[MAXN]; int get(int x){ return (x==ch[f[x]][1]); } int up(int x){ sz[x] = cnt[x]; if(ch[x][0])sz[x] = sz[x]+sz[ch[x][0]]; if(ch[x][1])sz[x] = sz[x]+sz[ch[x][1]]; return 0; } int down(int x){ if(tag[x]){ tag[x] = 0; swap(ch[x][0],ch[x][1]); if(ch[x][0])tag[ch[x][0]] = tag[ch[x][0]]^1; if(ch[x][1])tag[ch[x][1]] = tag[ch[x][1]]^1; } } int found(int x){ int now=rt,ans=1; while(1){ if(num[now]<=x){ ans = ans+sz[ch[now][0]]; if(num[now]==x){ return ans; } ans = ans+cnt[now]; now = ch[now][1]; } else{ now = ch[now][0]; } } } int rote(int x){ int y = f[x],z = f[y],k = get(x),p = get(y); down(y),down(x); if(y==0)return 0; if(z)ch[z][p] = x; if(ch[x][k^1])f[ch[x][k^1]] = y; ch[y][k] = ch[x][k^1]; ch[x][k^1] = y; f[x] = z; f[y] = x; up(y);up(x); return 0; } int splay(int x){ for(int y = f[x];(y = f[x]);rote(x)){ rote((get(x)==get(y))?y:x); } rt = x; return 0; } int rank(int x){ int now=rt,ans=1; while(1){ if(num[now]<=x){ ans = ans+sz[ch[now][0]]; if(num[now]==x){ splay(now); return ans; } ans = ans+cnt[now]; now = ch[now][1]; } else{ now = ch[now][0]; } } } int pre(){//前继 比她小的最大 int now = ch[rt][0]; while(ch[now][1])now = ch[now][1]; return now; } int suc(){ int now = ch[rt][1]; while(ch[now][0])now = ch[now][0]; return now; } int add(int x){ int now = rt; while(1){ down(now); if(num[now]==x){ cnt[now]++; splay(now); return 0; } int to = (num[now]<x); if(!ch[now][to]){ tot++; ch[now][to] = tot; num[tot] = x; f[tot] = now; cnt[tot] = 1; sz[tot] = 1; splay(tot); return 0; } else now = ch[now][to]; } } int kth(int x){ int now =rt; while(1){ down(now); if(sz[ch[now][0]]<x){ x = x-sz[ch[now][0]]; if(x<=cnt[now])return num[now]; x = x-cnt[now]; now = ch[now][1]; } else{ now = ch[now][0]; } } } int del(int x){ rank(x); if(cnt[rt]>=2){ cnt[rt]--; sz[rt]--; return 0; } else{ if((!ch[rt][0])&&(!ch[rt][1])){ rt = 0; return 0; } if(ch[rt][0]&&(!ch[rt][1])){ f[ch[rt][0]] = 0; rt =ch[rt][0]; return 0; } if((!ch[rt][0])&&ch[rt][1]){ f[ch[rt][1]] = 0; rt =ch[rt][1]; return 0; } else{ splay(pre()); ch[rt][1] = ch[ch[rt][1]][1]; f[ch[rt][1]] = rt; up(rt); return 0; } } } int splay2(int x){ for(int y = f[x];(y = f[x])!=rt;rote(x)){ if(f[y]!=rt)rote((get(x)==get(y))?y:x); } return 0; } int turn(int x,int g){ int p=kth(x-1),k=kth(g+1); splay(p); splay2(k); tag[ch[ch[rt][1]][0]] = 1^tag[ch[ch[rt][1]][0]]; } int print(int now){ down(now); if(ch[now][0])print(ch[now][0]); if(num[now]>1&&num[now]<n+2)cout<<num[now]-1<<" "; if(ch[now][1])print(ch[now][1]); } }T; int main(){ cin>>n>>m; for(int i=1;i<=n+2;i++)T.add(i); for(int i=1;i<=m;i++){ cin>>a>>b; T.turn(a+1,b+1); } T.print(T.rt); }
很好的模板题
以上是关于文艺平衡树的主要内容,如果未能解决你的问题,请参考以下文章