SPOJ 2939 QTREE5 LCT
维护信息的方式十分巧妙~
维护每一棵 splay 中深度最浅,深度最深的点距离最近的白点.
这样非常方便维护,进行区间合并,进行子树维护
因为动态树是可以维护子树信息的,也可以 ,所以如果维护深度最深的信息的话只需
code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | #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; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步