萌新初学OI,求助树剖板子
查看原帖
萌新初学OI,求助树剖板子
246019
Elma_楼主2020/8/3 23:16

rtrt,样例过不去,有输入没输出,一提交就是又WA又MLE……

怀疑是哪里写炸了爆栈了……然而没调出来……

有神仙帮忙看看吗/kel

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define maxn 200005
using namespace std;

inline int read()
{
	int x = 0, w = 1;char ch = getchar();
	while (ch > '9' || ch < '0') { if (ch == '-')w = -1;ch = getchar(); }
	while (ch >= '0' && ch <= '9')x = x * 10 + ch - '0', ch = getchar();
	return x * w;
}

struct node
{
	int to, nxt;
}edge[maxn];
int n, m, r, mod, dfs_block, tot, res;
int head[maxn], val[maxn], a[maxn], tree[maxn << 2], tag[maxn << 2];
int son[maxn], dfn[maxn], fa[maxn], dep[maxn], siz[maxn], top[maxn];

inline int lson(int x) { return x << 1; }
inline int rson(int x) { return x << 1 | 1; }
inline void push_up(int x) { tree[x] = (tree[lson(x)] + tree[rson(x)]) % mod; }
inline void add(int u, int v) { edge[++tot].nxt = head[u];edge[tot].to = v;head[u] = tot; }
inline void addedge(int u, int v) { add(u, v), add(v, u); }
inline void push_down(int x, int len)
{
	if (tag[x])
	{
		tag[lson(x)] += tag[x];
		tag[rson(x)] += tag[x];
		tree[lson(x)] += tag[x] * (len - (len >> 1));tree[lson(x)] %= mod;
		tree[rson(x)] += tag[x] * (len >> 1);tree[rson(x)] %= mod;
		tag[x] = 0;
	}
}

void build(int x, int l, int r)
{
	if (l == r)
	{
		tree[x] = a[l];
		if (tree[x] > mod) tree[x] %= mod;
		return;
	}
	int mid = (l + r) >> 1;
	build(lson(x), l, mid);
	build(rson(x), mid + 1, r);
	push_up(x);
}

int query(int x, int l, int r, int L, int R)
{
	if (l >= L && r <= R) { return tree[x] % mod; }
	push_down(x, r - l + 1);
	int mid = (l + r) >> 1, res = 0;
	if (L <= mid) res += query(lson(x), l, mid, L, R);
	if (R > mid) res += query(rson(x), mid + 1, r, L, R);
    return res;
}

void modify(int x, int l, int r, int L, int R, int k)
{
	if (l >= L && r <= R)
	{
		tag[x] += k;
		tree[x] += k * (r - l + 1);
		return;
	}
	push_down(x, r - l + 1);
	int mid = (l + r) >> 1;
	if (L <= mid) modify(lson(x), l, mid, L, R, k);
	if (R > mid) modify(rson(x), mid + 1, r, L, R, k);
	push_up(x);
}

int query_chain(int x, int y)
{
	int query_res = 0;
	while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		query_res += query(1, 1, n, dfn[top[x]], dfn[x]);
		query_res %= mod;
		x = fa[top[x]];
	}
	if (dep[x] > dep[y]) swap(x, y);
	query_res += query(1, 1, n, dfn[x], dfn[y]);
	return query_res % mod;
}

void modify_chain(int x, int y, int k)
{
	k %= mod;
	while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		modify(1, 1, n, dfn[top[x]], dfn[x], k);
		x = fa[top[x]];
	}
	if (dep[x] > dep[y]) swap(x, y);
	modify(1, 1, n, dfn[x], dfn[y], k);
}

int query_son(int x) { return query(1, 1, n, dfn[x], dfn[x] + siz[x] - 1);}
void modify_son(int x, int k) { k %= mod, modify(1, 1, n, dfn[x], dfn[x] + siz[x] - 1, k); }

void dfs1(int u, int fath)
{
	dep[u] = dep[fath] + 1;fa[u] = fath;
	son[u] = 0;siz[u] = 1;
	for (int i = head[u];i;i = edge[i].nxt)
	{
		int v = edge[i].to;
		if (v == fath) continue;
		dfs1(v, u), siz[u] += siz[v];
		if (siz[v] > siz[son[u]])
			son[u] = v;
	}
}

void dfs2(int u)
{
	dfn[u] = ++dfs_block, a[dfs_block] = val[u];
	if (u == son[fa[u]]) top[u] = top[fa[u]];
	else top[u] = u;
	if (son[u]) dfs2(son[u]);
	for (int i = head[u];i;i = edge[i].nxt)
	{
		int v = edge[i].to;
		if (v != fa[u] && v != son[u]) dfs2(v);
	}
}

int main(void)
{
	n = read(), m = read(), r = read(), mod = read();
	for (int i = 1;i <= n;i++) val[i] = read();
	for (int i = 1;i <= n;i++)
	{
		int u = read(), v = read();
		addedge(u, v);
	}
	dfs1(r, 0), dfs2(r);
	build(1, 1, n);
	while (m--)
	{
		int op = read();
		if (op == 1)
		{
			int x = read(), y = read(), z = read();
			modify_chain(x, y, z);
		}
		else if (op == 2)
		{
			int x = read(), y = read();
			printf("%d\n", query_chain(x, y));
		}
		else if(op == 3)
		{
			int x = read(), y = read();
			modify_son(x, y);
		}
		else if (op == 4)
		{
			int x = read();
			printf("%d\n", query_son(x));
		}
	}
	return 0;
}
2020/8/3 23:16
加载中...