【重链剖分】洛谷 P2590 树的统计
2021-06-04 18:13:00 # ACM

题链

树链剖分模板题,注意$a_i$数据范围就好

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
154
155
156
//#include <bits/stdc++.h>
#include <iostream>
#include <vector>
using namespace std;
#define ls rt<<1
#define rs rt<<1|1
#define LL long long
#define PI acos(-1.0)
#define eps 1e-8
#define Pair pair<double,double>
// notice
#define mod 998244353
#define MAXN 2e6
#define MS 30009

LL n,m;
LL a[MS];
vector<LL > vc[MS];
LL sz[MS];
LL fa[MS];
LL dep[MS];
LL zson[MS];
LL tot;
LL dfn[MS];
LL top[MS];
LL w[MS];
struct node{
LL maxn,val;
}p[MS<<2];

void dfs1(LL x,LL f){
sz[x] = 1;
fa[x] = f;
dep[x] = dep[f]+1;
int maxzson = 0;
for(auto &i:vc[x]){
if(i != f){
dfs1(i,x);
sz[x] += sz[i];
if(sz[i] >= maxzson){
maxzson = sz[i];
zson[x] = i;
}
}
}
}

void dfs2(LL x,LL tp){
dfn[x] = ++tot;
top[x] = tp;
w[tot] = a[x];
if(zson[x]) dfs2(zson[x],tp);
for(auto &i:vc[x]){
if(i != zson[x] && i != fa[x]){
dfs2(i,i);
}
}
}

void push_up(int rt){
p[rt].val = p[ls].val + p[rs].val;
p[rt].maxn = max(p[ls].maxn,p[rs].maxn);
}

void build(int l,int r,int rt){
if(l == r){
p[rt] = {w[l],w[l]};
return;
}
int m = l+r>>1;
build(l,m,ls);
build(m+1,r,rs);
push_up(rt);
}

void update(int pos,int l,int r,int rt,LL val){
if(l == r){
p[rt] = {val,val};
return;
}
int m = l+r>>1;
if(m >= pos) update(pos,l,m,ls,val);
else update(pos,m+1,r,rs,val);
push_up(rt);
}

node query(int L,int R,int l,int r,int rt){
if(L <= l && r <= R){
return p[rt];
}
int m = l+r>>1;
if(m < L) return query(L,R,m+1,r,rs);
else if(m >= R) return query(L,R,l,m,ls);
else{
node t1 = query(L,R,l,m,ls);
node t2 = query(L,R,m+1,r,rs);
node ans;
ans.val = t1.val + t2.val;
ans.maxn = max(t1.maxn,t2.maxn);
return ans;
}
}

node op23(LL x,LL y){
node ans = {-(LL)MAXN,0};
while(top[x] != top[y]){
if(dep[ top[x] ] < dep[ top[y] ]) swap(x,y);
node cc = query(dfn[top[x]],dfn[x],1,n,1);
ans.val += cc.val;
ans.maxn = max(ans.maxn,cc.maxn);
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x,y);
node cc = query(dfn[x],dfn[y],1,n,1);
ans.val += cc.val;
ans.maxn = max(ans.maxn,cc.maxn);
return ans;
}

void change(LL pos,LL val){
update(dfn[pos],1,n,1,val);
}

int main() {
ios::sync_with_stdio(false);
cin >> n;
for(int i=2;i<=n;i++){
LL u,v;
cin >> u >> v;
vc[u].push_back(v);
vc[v].push_back(u);
}
for(int i=1;i<=n;i++){
cin >> a[i];
}
dfs1(1,1);
dfs2(1,1);
build(1,n,1);
cin >> m;
while(m--){
char s[10];
LL x,y;
cin >> s >> x >> y;
if(s[0] == 'Q'){
node ans = op23(x,y);
if(s[1] == 'M') cout << ans.maxn << "\n";
else if(s[1] == 'S') cout << ans.val << "\n";
}
else if(s[0] == 'C'){
change(x,y);
}
}


return 0;
}
Prev
2021-06-04 18:13:00 # ACM
Next