S+8-树上算法
A. 苹果树2
- 用线段树去维护dfs序的连续性
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
using namespace std;
int n,m,tot;
int A[M],to[M];
int L[M],R[M];
vector<int>Q[M];
class {
public:
int l,r,v;
} tree[M<<2];
void dfs(int x,int q) {
L[x]=++tot,to[tot]=x;
for(int i=0; i<Q[x].size(); ++i) {
int y=Q[x][i];
if(y==q)continue;
dfs(y,x);
}
R[x]=tot;
}
int Max(int a,int b) {
if(A[a]>A[b])return a;
if(A[b]>A[a])return b;
if(a<b)return a;
return b;
}
int build(int L,int R,int p) {
tree[p].l=L,tree[p].r=R;
if(L==R)return tree[p].v=to[L];
int mid=L+R>>1;
return tree[p].v=Max(build(L,mid,p<<1),build(mid+1,R,p<<1|1));
}
void Up(int x,int p) {
if(tree[p].l==tree[p].r)return;
int mid=tree[p].l+tree[p].r>>1;
if(x<=mid)Up(x,p<<1);
else Up(x,p<<1|1);
tree[p].v=Max(tree[p<<1].v,tree[p<<1|1].v);
}
int query(int L,int R,int p) {
// printf("tree[p].l=%d tree[p].r=%d p=%d\n",tree[p].l,tree[p].r,p);
if(tree[p].l==L&&tree[p].r==R)return tree[p].v;
int mid=tree[p].l+tree[p].r>>1;
if(R<=mid)return query(L,R,p<<1);
if(L>mid)return query(L,R,p<<1|1);
return Max(query(L,mid,p<<1),query(mid+1,R,p<<1|1));
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1; i<=n; ++i)
scanf("%d",&A[i]);
for(int i=1; i<n; ++i) {
int u,v;
scanf("%d%d",&u,&v);
Q[u].push_back(v);
Q[v].push_back(u);
}
dfs(1,0);
build(1,n,1);
for(int i=1; i<=m; ++i) {
int c,x,y;
scanf("%d%d",&c,&x);
if(c<2) {
printf("%d\n",y=query(L[x],R[x],1));
A[y]=0;
Up(L[y],1);
} else {
scanf("%d",&y);
A[x]+=y;
Up(L[x],1);
}
}
return 0;
}
B. LCA查询
双指针算最大LCA
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ysmmm的快乐小屋!