社区讨论
WA 50pts 求助
P3178[HAOI2015] 树上操作参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @lo8xxcu3
- 此快照首次捕获于
- 2023/10/28 02:22 2 年前
- 此快照最后确认于
- 2023/10/28 02:22 2 年前
CPP
#include <bits/stdc++.h>
using namespace std;
int n, m, root, dfs[1000006][2], dfn[2000006], cnt;
vector<int> g[1000006];
bitset<1000006> flag;
class node
{
public:
int chainhd;
int deep;
int fa;
int hson;
long long int val;
int weight;
vector<int> child;
};
node tree[1000006];
class segment
{
public:
int l;
int r;
long long int lag;
long long int sum;
};
segment t[8000006];
template <typename T>
inline void read(T &x)
{
x = 0;
int f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-')
f = -1;
c = getchar();
}
while ('0' <= c && c <= '9')
{
x = (x << 1) + (x << 3) + c - '0';
c = getchar();
}
x *= f;
}
template <typename T>
void write(T x)
{
if (x < 0)
x = -x, putchar('-');
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
void init(int x, int deep)
{
flag[x] = true;
tree[x].deep = deep;
tree[x].weight = 1;
for (auto i : g[x])
{
if (!flag[i])
{
tree[i].fa = x;
tree[x].child.push_back(i);
init(i, deep + 1);
tree[x].weight += tree[i].weight;
if (tree[i].weight > tree[tree[x].hson].weight)
{
tree[x].hson = i;
}
}
}
}
void subdivision(int id, int chainhd)
{
dfs[id][0] = ++cnt;
dfn[cnt] = id;
tree[id].chainhd = chainhd;
if (tree[id].hson != 0)
{
subdivision(tree[id].hson, chainhd);
}
for (auto i : tree[id].child)
{
if (i != tree[id].hson)
{
subdivision(i, i);
}
}
dfs[id][1] = ++cnt;
dfn[cnt] = id;
}
void init(int id, int l, int r)
{
t[id].l = l;
t[id].r = r;
if (l == r)
{
t[id].sum = tree[dfn[l]].val;
return;
}
int mid = (l + r) >> 1;
init(id << 1, l, mid);
init((id << 1) + 1, mid + 1, r);
t[id].sum = t[id << 1].sum + t[(id << 1) + 1].sum;
}
void update(int id)
{
t[id << 1].lag += t[id].lag;
t[(id << 1) + 1].lag += t[id].lag;
t[id << 1].sum += (t[id << 1].r - t[id << 1].l + 1) * t[id].lag;
t[(id << 1) + 1].sum += (t[(id << 1) + 1].r - t[(id << 1) + 1].l + 1) * t[id].lag;
t[id].lag = 0;
}
void add(int id, int l, int r, long long int delta)
{
if (t[id].l >= l && t[id].r <= r)
{
t[id].lag += delta;
t[id].sum += (t[id].r - t[id].l + 1) * delta;
return;
}
update(id);
int mid = (t[id].l + t[id].r) >> 1;
if (l <= mid)
{
add(id << 1, l, r, delta);
}
if (r > mid)
{
add((id << 1) + 1, l, r, delta);
}
t[id].sum = t[id << 1].sum + t[(id << 1) + 1].sum;
}
void add(int id, int pos, long long int delta)
{
if (t[id].l == t[id].r)
{
t[id].sum += delta;
return;
}
update(id);
int mid = (t[id].l + t[id].r) >> 1;
if (pos <= mid)
{
add(id << 1, pos, delta);
}
else
{
add((id << 1) + 1, pos, delta);
}
t[id].sum = t[id << 1].sum + t[(id << 1) + 1].sum;
}
long long int qsum(int id, int l, int r)
{
if (t[id].l >= l && t[id].r <= r)
{
return t[id].sum;
}
update(id);
int mid = (t[id].l + t[id].r) >> 1;
int rev = 0;
if (l <= mid)
{
rev += qsum(id << 1, l, r);
}
if (r > mid)
{
rev += qsum((id << 1) + 1, l, r);
}
return rev;
}
long long int QSUM(int x)
{
int rev = 0;
while (tree[x].chainhd != tree[1].chainhd)
{
rev += qsum(1, dfs[tree[x].chainhd][0], dfs[x][0]);
x = tree[tree[x].chainhd].fa;
}
rev += qsum(1, dfs[1][0], dfs[x][0]);
return rev;
}
int main()
{
read(n);
read(m);
for (int i = 1; i <= n; i++)
{
read(tree[i].val);
}
for (int i = 1; i < n; i++)
{
int u, v;
read(u);
read(v);
g[u].push_back(v);
g[v].push_back(u);
}
root = 1;
tree[root].fa = root;
init(root, 1);
subdivision(1, 1);
init(1, 1, cnt);
for (int i = 1; i <= m; i++)
{
int op;
read(op);
if (op == 1)
{
int u;
long long int t;
read(u);
read(t);
tree[u].val += t;
add(1, dfs[u][0], t);
add(1, dfs[u][1], t);
}
else if (op == 2)
{
int u;
long long int t;
read(u);
read(t);
add(1, dfs[u][0], dfs[u][1], t);
}
else
{
int u;
read(u);
write(QSUM(u));
putchar('\n');
}
}
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...