SPOJ 2939 QTREE5 LCT

维护信息的方式十分巧妙~

维护每一棵 splay 中深度最浅,深度最深的点距离最近的白点.   

这样非常方便维护,进行区间合并,进行子树维护 

很多时候在维护东西的时候最大/最小/深度最小/深度最大会相对容易维护,所以如果用树剖/LCT维护信息时发现很难维护的话可以采用这种套路.

因为动态树是可以维护子树信息的,也可以 ,所以如果维护深度最深的信息的话只需 就可以做到.

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;
}

  

posted @   EM-LGH  阅读(138)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示