BZOJ1103: [POI2007]大都市meg

BZOJ1103: [POI2007]大都市meg

Description

在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了。
不过,她经常回忆起以前在乡间漫步的情景。

昔日,乡下有依次编号为1..n的n个小村庄,某些村庄之间有一些双向的土路。

从每个村庄都恰好有一条路径到达村庄1(即比特堡)。

并且,对于每个村庄,它到比特堡的路径恰好只经过编号比它的编号小的村庄。

另外,对于所有道路而言,它们都不在除村庄以外的其他地点相遇。

在这个未开化的地方,从来没有过高架桥和地下铁道。

随着时间的推移,越来越多的土路被改造成了公路。

至今,Blue Mary还清晰地记得最后一条土路被改造为公路的情景。

现在,这里已经没有土路了——所有的路都成为了公路,而昔日的村庄已经变成了一个大都市。

Blue Mary想起了在改造期间她送信的经历。

她从比特堡出发,需要去某个村庄,并且在两次送信经历的间隔期间,有某些土路被改造成了公路.

现在Blue Mary需要你的帮助:

计算出每次送信她需要走过的土路数目。(对于公路,她可以骑摩托车;而对于土路,她就只好推车了。)

Input

第一行是一个数n(1 < = n < = 2 50000).

以下n-1行,每行两个整数a,b(1 < =  a

以下一行包含一个整数m(1 < = m < = 2 50000),表示Blue Mary曾经在改造期间送过m次信。

以下n+m-1行,每行有两种格式的若干信息,表示按时间先后发生过的n+m-1次事件:

若这行为 A a b(a

若这行为 W a, 则表示Blue Mary曾经从比特堡送信到村庄a。

Output

  有m行,每行包含一个整数,表示对应的某次送信时经过的土路数目。

Sample Input

5
1 2
1 3
1 4
4 5
4
W 5
A 1 4
W 5
A 4 5
W 5
W 2
A 1 2
A 1 3

Sample Output

2
1
0
1

HINT

题解Here!

树链剖分水题。。。

附代码:

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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include<iostream>
#include<algorithm>
#include<cstdio>
#define LSON rt<<1
#define RSON rt<<1|1
#define DATA(x) b[x].data
#define SIGN(x) b[x].c
#define LSIDE(x) b[x].l
#define RSIDE(x) b[x].r
#define WIDTH(x) (RSIDE(x)-LSIDE(x)+1)
#define MAXN 250010
using namespace std;
int n,m,c=1,d=1;
int head[MAXN],deep[MAXN],son[MAXN],size[MAXN],fa[MAXN],id[MAXN],top[MAXN];
struct Graph{
    int next,to;
}a[MAXN<<1];
struct Segment_Tree{
    int data,c,l,r;
}b[MAXN<<2];
inline int read(){
    int date=0,w=1;char c=0,last=0;
    while(c<'0'||c>'9'){last=c;c=getchar();}
    while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
    if(last=='-')w=-1;
    return date*w;
}
inline void pushup(int rt){
    DATA(rt)=DATA(LSON)+DATA(RSON);
}
inline void pushdown(int rt){
    if(SIGN(rt)==-1||LSIDE(rt)==RSIDE(rt))return;
    SIGN(LSON)=SIGN(rt);
    DATA(LSON)=SIGN(rt)*WIDTH(LSON);
    SIGN(RSON)=SIGN(rt);
    DATA(RSON)=SIGN(rt)*WIDTH(RSON);
    SIGN(rt)=-1;
}
void buildtree(int l,int r,int rt){
    int mid;
    LSIDE(rt)=l;
    RSIDE(rt)=r;
    SIGN(rt)=-1;
    if(l==r){
        DATA(rt)=1;
        if(l==1)DATA(rt)=0;
        return;
    }
    mid=l+r>>1;
    buildtree(l,mid,LSON);
    buildtree(mid+1,r,RSON);
    pushup(rt);
}
void update(int l,int r,int c,int rt){
    int mid;
    if(l<=LSIDE(rt)&&RSIDE(rt)<=r){
        SIGN(rt)=c;
        DATA(rt)=c*WIDTH(rt);
        return;
    }
    pushdown(rt);
    mid=LSIDE(rt)+RSIDE(rt)>>1;
    if(l<=mid)update(l,r,c,LSON);
    if(mid<r)update(l,r,c,RSON);
    pushup(rt);
}
int query(int l,int r,int rt){
    int mid,ans=0;
    if(l<=LSIDE(rt)&&RSIDE(rt)<=r)return DATA(rt);
    pushdown(rt);
    mid=LSIDE(rt)+RSIDE(rt)>>1;
    if(l<=mid)ans+=query(l,r,LSON);
    if(mid<r)ans+=query(l,r,RSON);
    return ans;
}
inline void add(int x,int y){
    a[c].to=y;a[c].next=head[x];head[x]=c++;
    a[c].to=x;a[c].next=head[y];head[y]=c++;
}
void dfs1(int rt){
    son[rt]=0;size[rt]=1;
    for(int i=head[rt];i;i=a[i].next){
        int will=a[i].to;
        if(!deep[will]){
            deep[will]=deep[rt]+1;
            fa[will]=rt;
            dfs1(will);
            size[rt]+=size[will];
            if(size[son[rt]]<size[will])son[rt]=will;
        }
    }
}
void dfs2(int rt,int f){
    id[rt]=d++;top[rt]=f;
    if(son[rt])dfs2(son[rt],f);
    for(int i=head[rt];i;i=a[i].next){
        int will=a[i].to;
        if(will!=fa[rt]&&will!=son[rt])
        dfs2(will,will);
    }
}
void work_change(int x,int y){
    while(top[x]!=top[y]){
        if(deep[top[x]]<deep[top[y]])swap(x,y);
        update(id[top[x]],id[x],0,1);
        x=fa[top[x]];
    }
    if(deep[x]>deep[y])swap(x,y);
    update(id[x]+1,id[y],0,1);
    return;
}
void work_sum(int x,int y){
    int s=0;
    while(top[x]!=top[y]){
        if(deep[top[x]]<deep[top[y]])swap(x,y);
        s+=query(id[top[x]],id[x],1);
        x=fa[top[x]];
    }
    if(deep[x]>deep[y])swap(x,y);
    s+=query(id[x]+1,id[y],1);
    printf("%d\n",s);
    return;
}
void work(){
    char ch[2];
    int x,y;
    m=read()+n-1;
    while(m--){
        scanf("%s",ch);x=read();
        if(ch[0]=='A'){
            y=read();
            work_change(x,y);
        }
        else work_sum(1,x);
    }
}
void init(){
    int x,y;
    n=read();
    for(int i=1;i<n;i++){
        x=read();y=read();
        add(x,y);
    }
    deep[1]=1;
    dfs1(1);
    dfs2(1,1);
    buildtree(1,n,1);
}
int main(){
    init();
    work();
    return 0;
}

 

posted @   符拉迪沃斯托克  阅读(190)  评论(0编辑  收藏  举报
Live2D
欢迎阅读『BZOJ1103: [POI2007]大都市meg』
点击右上角即可分享
微信分享提示