刚学树剖1s求助
查看原帖
刚学树剖1s求助
81832
Starry___sky楼主2020/8/28 22:06

为啥我全WA T_T, 我上一道题就调了好久

#include<bits/stdc++.h>

#define ll long long
#define ls(k) k << 1
#define rs(k) k << 1 | 1

using namespace std;

const int N = 1e5 + 10;

struct EDGE{
	ll to, next;
}edge[N << 1];
ll head[N], num = 0;
void addedge(ll x, ll y)
{
	edge[++num].next = head[x];
	edge[num].to = y;
	head[x] = num;
}

ll tree[N << 2], tag[N << 2], val[N];

ll top[N], dep[N], fa[N], size[N], son[N], seg[N], rev[N];

ll n, m;

void dfs1(ll u, ll f)
{
	fa[u] = f;
	dep[u] = dep[f] + 1;
	size[u] = 1;
	for(ll i = head[u]; i; i = edge[i].next)
	{
		ll v = edge[i].to;
		if(v == f)
			continue;
		dfs1(v, u);
		size[u] += size[v];
		if(size[v] > size[son[u]])
			son[u] = v;
	}
}

void dfs2(ll u, ll t)
{
	top[u] = t;
	seg[u] = ++seg[0];
	rev[seg[0]] = u;
	if(son[u])
		dfs2(son[u], t);	
	for(ll i = head[u]; i; i = edge[i].next)
	{
		ll v = edge[i].to;
		if(v == son[u] || v == fa[u])
			continue;
		dfs2(v, v);
	}
}

void build(ll k, ll l, ll r)
{
	tree[k] = 0;
	tag[k] = 0;
	if(l == r)
	{
		tree[k] = val[rev[l]];
		return;
	}
	ll mid = (l + r) >> 1;
	build(ls(k), l, mid);
	build(rs(k), mid + 1, r);
	tree[k] = tree[ls(k)] + tree[rs(k)];
}

void add(ll k, ll l, ll r, ll v)
{
	tag[k] += v;
	tree[k] += (r - l + 1) * v;
}

void push_down(ll k, ll l, ll r, ll mid)
{
	if(!tag[k])
		return;
	add(ls(k), l, mid, tag[k]);
	add(rs(k), mid + 1, r, tag[k]);
	tag[k] = 0;
}

void modify(ll k, ll l,ll r, ll x, ll v)
{
	if(l == r && l == x)
	{
		tree[k] += v;
		return;
	}
	ll mid = (l + r) >> 1;
	push_down(k, l, r, mid);
	if(x <= mid)
		modify(ls(k), l, mid, x, v);
	else
		modify(rs(k), mid + 1, r, x, v);
	tree[k] = tree[ls(k)] + tree[rs(k)];
}

void change(ll k, ll l, ll r, ll x, ll y, ll v)
{
	if(x <= l && r <= y)
	{
		add(k, l, r, v);
		return;
	}
	ll mid = (l + r) >> 1;
	push_down(k, l, r, mid);
	if(x <= mid)
		change(ls(k), l, mid, x, y, v);
	if(y > mid)
		change(rs(k), mid + 1, r, x, y, v);
	tree[k] = tree[ls(k)] + tree[rs(k)];
}

ll query(ll k, ll l, ll r, ll x, ll y)
{
	if(x <= l && r <= y)
		return tree[k];
	ll mid = (l + r) >> 1;
	push_down(k, l, r, mid);
	ll ans = 0;
	if(x <= mid)
		ans += query(ls(k), l, mid, x, y);
	if(y > mid)
		ans += query(rs(k), mid + 1, r , x, y);
	return ans;
}

ll ask(ll x)
{
	ll ans = 0;
	while(top[x] != 1)
	{
		ans += query(1, 1, seg[0], seg[x], seg[top[x]]);
		x = fa[top[x]];
	}
	ans += query(1, 1, seg[0], seg[1], seg[x]);
	return ans;
}

int main()
{
	cin >> n >> m;
	for(ll i = 1; i <= n; i++)
		cin >> val[i];
	for(ll i = 1; i <= n - 1; i++)
	{
		ll x, y;
		cin >> x >> y;
		addedge(x, y);
		addedge(y, x);
	}
	dfs1(1, 0);
	seg[0] = 0;
	dfs2(1, 1);
	build(1, 1, seg[0]);
	while(m--)
	{
		ll op;
		cin >> op;
		if(op == 1)
		{
			ll x, a;
			cin >> x >> a;
			modify(1, 1, seg[0], x, a);	
		}
		else if(op == 2)
		{
			ll x, a;
			cin >> x >> a;
			change(1, 1, seg[0], seg[x], seg[x] + size[x] - 1, a);
		}
		else if(op == 3)
		{
			ll x;
			cin >> x;
			ll ans = ask(x);
			cout << ans << endl;
		}
	}
	return 0;
}
2020/8/28 22:06
加载中...