http://www.spoj.com/problems/QTREE5/en/
看别人代码理解的LCT。。。
加入set维护虚边
想了好久,终于明白up()函数是什么意思了。。。。
不明白为什么可以没有flip,而且根本不会加flip
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <cmath> #include <algorithm> #include <set> using namespace std; #define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++) #define per(i,r,l) for(int i=(r),_=(l);i>=_;i--) #define MS(arr,x) memset(arr,x,sizeof(arr)) #define INE(i,u) for(int i=head[u];~i;i=e[i].next) #define LL long long #define LS c[0] #define RS c[1] inline const int read() {int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1; for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;} int min(int a,int b,int c){return min(min(a,b),c);} //////////////////////////////////////////////// const int inf=0x3f3f3f3f; const int N=100010; int n; struct edge{int v,next;}e[N*2]; int head[N],k; struct node *null; struct node{ node *c[2],*fa; bool d(){return this==fa->RS;} void setc(node *ch,bool d){c[d]=ch;ch->fa=this;} bool isroot(){return this!=fa->LS&&this!=fa->RS;} bool rev; int d0,l; int uu,dd,w; multiset<int>S; void erase(int x) { S.erase(S.find(x)); } void insert(int x) { S.insert(x); } void _flip() { rev^=1; swap(LS,RS); swap(uu,dd); } void up() { if(this==null) return; l=LS->l+RS->l+d0; uu=min(LS->uu,d0+min(w,*S.begin(),RS->uu)+LS->l); dd=min(RS->dd,min(w,*S.begin(),LS->dd+d0)+RS->l); } void down() { if(this==null) return; if(rev) { LS->_flip(); RS->_flip(); rev=0; } } void init() { LS=RS=fa=null; rev=0; d0=l=0; uu=dd=w=inf; S.clear(); insert(inf); } }T[N]; //////////////////////////////////////////////// void adde(int u,int v){e[k]=(edge){v,head[u]};head[u]=k++;} void rot(node *o) { node *f=o->fa; f->down(); o->down(); bool d=o->d(); if(!f->isroot()) f->fa->setc(o,f->d()); else o->fa=f->fa; f->setc(o->c[!d],d); o->setc(f,!d); f->up(); } void splay(node *o) { for(o->down();!o->isroot();rot(o)); o->up(); } void access(node *o) { for(node *t=null;o!=null;t=o,o=o->fa) { splay(o); if(o->RS!=null) { o->insert(o->RS->uu); } if(t!=null) { o->erase(t->uu); } t->down(); o->RS=t; } } void makeroot(node *o) { access(o); splay(o); o->_flip(); } void dfs(int u,int fa) { INE(i,u) { int v=e[i].v; if(v==fa) continue; T[v].fa=&T[u]; T[v].d0=1; dfs(v,u); T[u].insert(T[v].uu); } T[u].up(); } void Flip(int u) { //makeroot(&T[u]); access(&T[u]); splay(&T[u]); T[u].w=inf-T[u].w; T[u].up(); } int Query(int u) { //makeroot(&T[u]); access(&T[u]); splay(&T[u]);// T[u]._flip(); if(T[u].dd<inf) return T[u].dd; else return -1; } //////////////////////////////////////////////// void input() { MS(head,-1); n=read(); rep(i,2,n) { int u=read(),v=read(); adde(u,v); adde(v,u); } } void solve() { null=&T[0]; null->init(); rep(i,1,n) T[i].init(); dfs(1,0); rep(__,1,read()) { if(read()==0) { int u=read(); Flip(u); } else { int u=read(); printf("%d\n",Query(u)); } } } //////////////////////////////////////////////// int main() { freopen("_.in","r",stdin); freopen("_.out","w",stdout); input(),solve(); return 0; }