SPOJ 2939 QTREE5 LCT
维护信息的方式十分巧妙~
维护每一棵 splay 中深度最浅,深度最深的点距离最近的白点.
这样非常方便维护,进行区间合并,进行子树维护
因为动态树是可以维护子树信息的,也可以 ,所以如果维护深度最深的信息的话只需
code:
#include <bits/stdc++.h> #define N 100006 #define inf 1000000 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int n,edges; int hd[N],to[N<<1],nex[N<<1],col[N]; void add(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } struct Link_Cut_Tree { #define lson p[x].ch[0] #define rson p[x].ch[1] struct Node { int ch[2],f,size,lmn,rmn; multiset<int>s; int get() { return s.empty()?inf:*s.begin(); } }p[N]; int get(int x) { return p[p[x].f].ch[1]==x; } int isrt(int x) { return !(p[p[x].f].ch[0]==x||p[p[x].f].ch[1]==x); } void pushup(int x) { p[x].size=p[lson].size+p[rson].size+1; p[x].lmn=min(p[lson].lmn, p[lson].size+min(col[x]?0:inf, min(p[x].get(), p[rson].lmn+1))); p[x].rmn=min(p[rson].rmn, p[rson].size+min(col[x]?0:inf, min(p[x].get(), p[lson].rmn+1))); } void rotate(int x) { int old=p[x].f,fold=p[old].f,which=get(x); if(!isrt(old)) p[fold].ch[p[fold].ch[1]==old]=x; p[old].ch[which]=p[x].ch[which^1],p[p[old].ch[which]].f=old; p[x].ch[which^1]=old,p[old].f=x,p[x].f=fold; pushup(old),pushup(x); } void splay(int x) { int u=x,v=0,fa; for(;!isrt(u);u=p[u].f); for(u=p[u].f;(fa=p[x].f)!=u;rotate(x)) if(p[fa].f!=u) rotate(get(fa)==get(x)?fa:x); } void Access(int x) { for(int y=0;x;y=x,x=p[x].f) { splay(x); if(rson) { p[x].s.insert(p[rson].lmn+1); } if(y) { p[x].s.erase(p[x].s.find(p[y].lmn+1)); } rson=y; pushup(x); } } #undef lson #undef rson }lct; void dfs(int u,int ff) { lct.p[u].f=ff; for(int i=hd[u];i;i=nex[i]) { int v=to[i]; if(v==ff) continue; dfs(v,u); lct.p[u].s.insert(inf+1); } lct.pushup(u); } int main() { // setIO("input"); int i,j; scanf("%d",&n); for(i=1;i<n;++i) { int u,v; scanf("%d%d",&u,&v); add(u,v); add(v,u); } lct.p[0].lmn=lct.p[0].rmn=inf; dfs(1,0); int m; scanf("%d",&m); for(i=1;i<=m;++i) { int op,u; scanf("%d%d",&op,&u); if(op==0) { lct.Access(u); lct.splay(u); col[u]^=1; lct.pushup(u); } else { lct.Access(u); lct.splay(u); printf("%d\n",lct.p[u].rmn>n?-1:lct.p[u].rmn); } } return 0; }