[BJOI2014]大融合 LCT維護子樹信息
阿新 • • 發佈:2018-12-12
%s hup pre lld += splay ota name make
Code:
#include <cstdio> #include <algorithm> #include <cstring> #include <string> using namespace std; void setIO(string a){freopen((a+".in").c_str(),"r",stdin);} #define maxn 100009 #define ll long long int n,q; struct LCT{ int ch[maxn][2],f[maxn],siz[maxn],sta[maxn],son[maxn],tag[maxn]; int lson(int x){ return ch[x][0]; } int rson(int x){ return ch[x][1]; } int get(int x){ return ch[f[x]][1]==x;} int isRoot(int x){ return !(ch[f[x]][0]==x||ch[f[x]][1]==x); } void mark(int x){ if(!x)return; swap(ch[x][0],ch[x][1]),tag[x]^=1; } void pushdown(int x){ if(tag[x]) mark(lson(x)),mark(rson(x)),tag[x]=0; } void pushup(int x){ if(!x) return; siz[x]=siz[lson(x)]+siz[rson(x)]+son[x]+1; } void rotate(int x){ int old=f[x],fold=f[old],which=get(x); if(!isRoot(old)) ch[fold][ch[fold][1]==old]=x; ch[old][which]=ch[x][which^1],f[ch[old][which]]=old; ch[x][which^1]=old,f[old]=x,f[x]=fold; pushup(old),pushup(x); } void splay(int x){ int v=0,u=x; sta[++v]=u; while(!isRoot(u)) sta[++v]=f[u],u=f[u]; while(v) pushdown(sta[v--]); u=f[u]; for(int fa;(fa=f[x])!=u;rotate(x)) if(f[fa]!=u) rotate(get(fa)==get(x)?fa:x); } void Access(int x){for(int y=0;x;y=x,x=f[x]) splay(x),son[x]=son[x]+siz[ch[x][1]]-siz[y], ch[x][1]=y, pushup(x); } void makeRoot(int x){ Access(x), splay(x), mark(x);} void link(int a,int b){ makeRoot(a), makeRoot(b), son[a]+=siz[b], f[b]=a, pushup(a); } ll query(int a,int b){ makeRoot(a),makeRoot(b); return (long long)siz[a]*(siz[b]-siz[a]); } }tree; int main(){ //setIO("input"); int a,b; char opt[5]; scanf("%d%d",&n,&q); while(q--){ scanf("%s%d%d",opt,&a,&b); switch(opt[0]){ case ‘A‘: { tree.link(a,b); break; } case ‘Q‘: { printf("%lld\n",tree.query(a,b)); break; } } } return 0; }
[BJOI2014]大融合 LCT維護子樹信息