「LOJ 145」DFS序 2

经典的DFS序入门

题目都告诉你是什么算法了

和「LOJ 144」DFS序 1一样,只不过这次把单点查询的树状数组改成区间修改的线段树罢了

敲下模板就结束了

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
#include <bits/stdc++.h>
#define ll long long

const int MaxN = 1000010;

struct edge
{
int to, next;
};

struct vertex
{
int dfn, next, val;
};

struct node
{
int l, r;
ll sum, tag;
};

struct SegmentTree
{
ll x[MaxN];
node t[MaxN << 2];
void pushup(int id) { t[id].sum = t[id << 1].sum + t[id << 1 | 1].sum; }
inline void build(int id, int l, int r)
{
t[id].l = l, t[id].r = r;
if (l == r)
{
t[id].sum = x[l];
return;
}
int mid = (l + r) >> 1;
build(id << 1, l, mid);
build(id << 1 | 1, mid + 1, r);
pushup(id);
}
inline void pushdown(int id)
{
if (t[id].tag)
{
t[id << 1].tag += t[id].tag;
t[id << 1 | 1].tag += t[id].tag;

t[id << 1].sum += t[id].tag * 1ll * (t[id << 1].r - t[id << 1].l + 1);
t[id << 1 | 1].sum += t[id].tag * 1ll * (t[id << 1 | 1].r - t[id << 1 | 1].l + 1);

t[id].tag = 0;
}
}
inline void modify(int id, int l, int r, int val)
{
if (l > t[id].r || r < t[id].l)
return;
if (l <= t[id].l && t[id].r <= r)
{
t[id].sum += val * 1ll * (t[id].r - t[id].l + 1);
t[id].tag += val;
return;
}
if (t[id].l == t[id].r)
return;
pushdown(id);
modify(id << 1, l, r, val);
modify(id << 1 | 1, l, r, val);
pushup(id);
}
inline ll query(int id, int l, int r)
{
if (l > t[id].r || r < t[id].l)
return 0;
if (l <= t[id].l && t[id].r <= r)
return t[id].sum;
if (t[id].l == t[id].r)
return 0;
pushdown(id);
return query(id << 1, l, r) + query(id << 1 | 1, l, r);
}
} T;

edge e[MaxN];
vertex a[MaxN];
int head[MaxN], vis[MaxN];
int n, m, r, cnt, dfscnt;

inline void add_edge(int u, int v)
{
++cnt;
e[cnt].to = v;
e[cnt].next = head[u];
head[u] = cnt;
}

inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while (ch > '9' || ch < '0')
{
if (ch == '-')
f = 0;
ch = getchar();
}
while (ch <= '9' && ch >= '0')
x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
return f ? x : (-x);
}

inline void dfs(int u)
{
a[u].dfn = vis[u] = ++dfscnt;
for (int i = head[u]; i; i = e[i].next)
{
int v = e[i].to;
if (vis[v])
continue;
dfs(v);
}
a[u].next = dfscnt;
}

int main()
{
n = read(), m = read(), r = read();
for (int i = 1; i <= n; ++i)
a[i].val = read();
for (int i = 1; i < n; i++)
{
int u = read(), v = read();
add_edge(u, v);
add_edge(v, u);
}
dfs(r);
for(int i = 1; i <= n; i++)
T.x[a[i].dfn] = a[i].val;
T.build(1, 1, n);
for (int i = 1; i <= m; i++)
{
int op = read();
if (op == 1)
{
int pos = read(), x = read();
T.modify(1, a[pos].dfn, a[pos].next, x);
}
else
{
int pos = read();
printf("%lld\n", T.query(1, a[pos].dfn, a[pos].next));
}
}
return 0;
}
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×