CF1137F Matches Are Not a Child's Play LCT+树状数组
这道题的思路很神啊 ~
#include <cstdio> #include <string> #include <cstring> #include <algorithm> using namespace std; const int N=200006; int cur_id; namespace IO { void setIO(string s) { string in=s+".in"; string out=s+".out"; freopen(in.c_str(),"r",stdin); // freopen(out.c_str(),"w",stdout); } }; namespace BIT { #define M 400006 int C[M]; #define lowbit(t) (t&(-t)) void update(int x,int v) { for(int i=x;i<M;i+=lowbit(i)) C[i]+=v; } int query(int x) { int tmp=0; for(int i=x;i>0;i-=lowbit(i)) tmp+=C[i]; return tmp; } }; namespace LCT { #define lson t[x].ch[0] #define rson t[x].ch[1] #define get(x) (t[t[x].f].ch[1]==x) #define Isrt(x)(!(t[t[x].f].ch[0]==x||t[t[x].f].ch[1]==x)) struct node { int ch[2],rev,f,size,id; }t[N]; int sta[N]; void Pushup(int x) { t[x].size=t[lson].size+t[rson].size+1; } void mark(int x) { t[x].rev^=1; swap(lson,rson); } void Pushdown(int x) { if(t[x].rev) { t[x].rev=0; if(lson) mark(lson); if(rson) mark(rson); } if(lson) t[lson].id=t[x].id; if(rson) t[rson].id=t[x].id; } void Rotate(int x) { int old=t[x].f; int fold=t[old].f; int which=get(x); if(!Isrt(old)) t[fold].ch[t[fold].ch[1]==old]=x; t[old].ch[which]=t[x].ch[which^1]; t[t[old].ch[which]].f=old; t[x].ch[which^1]=old; t[old].f=x; t[x].f=fold; Pushup(old); Pushup(x); } void Splay(int x) { int v=0,u=x,fa; for(sta[++v]=u;!Isrt(u);u=t[u].f) sta[++v]=t[u].f; for(;v;--v) Pushdown(sta[v]); for(u=t[u].f;(fa=t[x].f)!=u;Rotate(x)) { if(t[fa].f!=u) Rotate(get(fa)==get(x)?fa:x); } } void Access(int x) { for(int y=0;x;y=x,x=t[x].f) { Splay(x); rson=0; Pushup(x); BIT::update(t[x].id,-t[x].size); BIT::update(cur_id,t[x].size); rson=y; Pushup(x); } } void Move_Root(int x) { ++cur_id; Access(x),Splay(x),mark(x); t[x].id=cur_id; } }; int n,edges; int hd[N],to[N<<1],nex[N<<1]; int query(int x) { using namespace LCT; Splay(x); return BIT::query(t[x].id)-t[lson].size; } void add(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } void dfs(int u,int ff) { using namespace LCT; t[u].id=u; t[u].f=ff; for(int i=hd[u];i;i=nex[i]) { int v=to[i]; if(v==ff) continue; dfs(v,u); if(t[v].id>t[u].id) { t[u].id=t[v].id; t[u].ch[1]=v; Pushup(u); } } BIT::update(t[u].id,1); } int main() { // IO::setIO("input"); int i,j,m; scanf("%d%d",&n,&m); for(i=1;i<n;++i) { int x,y; scanf("%d%d",&x,&y); add(x,y),add(y,x); } dfs(n,0); cur_id=n; char str[12]; for(i=1;i<=m;++i) { int x,y; scanf("%s",str); if(str[0]=='w') { scanf("%d",&x),printf("%d\n",query(x)); } if(str[0]=='u') { scanf("%d",&x),LCT::Move_Root(x); } if(str[0]=='c') { scanf("%d%d",&x,&y),printf("%d\n",query(x)<query(y)?x:y); } } return 0; }