社区讨论

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 条回复,欢迎继续交流。

正在加载回复...