神奇的MLE了
查看原帖
神奇的MLE了
742017
zhangxiao666楼主2023/8/7 20:16
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5; 
int n, q, cnt;
int a[N], b[N];
int to[2 * N], nxt[2 * N], head[N];
int siz[N], fa[N], dep[N], son[N];
int id[N], top[N];
int trsum[4 * N], trmax[4 * N];

void add_edge(int x, int y)
{
	cnt++;
	nxt[cnt] = head[x];
	to[cnt] = y;
	head[x] = cnt;
}

void dfs1(int rt, int father)
{
	fa[rt] = father;
	siz[rt] = 1;
	dep[rt] = dep[father] + 1;
	int maxson = 0;
	for(int i = head[rt]; i ; i = nxt[i])
	{
		if(to[i] == father) continue;
		dfs1(to[i], rt);
		siz[rt] += siz[to[i]];
		if(siz[to[i]] > maxson) maxson = siz[rt], son[rt] = to[i];
	}
}

void dfs2(int rt, int ttop)
{
	id[rt] = ++cnt;
	top[rt] = ttop;
	a[cnt] = b[rt];
	if(!son[rt]) return;
	dfs2(son[rt], ttop);
	for(int i = head[rt]; i ; i = nxt[i])
	{
		if(id[to[i]] == 0) dfs2(to[i], to[i]);
	}
}

void pushup(int now)
{
	trsum[now] = trsum[now << 1] + trsum[now<< 1 | 1];
	trmax[now] = max(trmax[now << 1], trmax[now << 1 | 1]);
}

void build(int now, int l, int r)
{
	if(l == r) {trmax[now] = trsum[now] = a[l]; return ;}
	int mid = (l + r) >> 1;
	build(now << 1, l, mid);
	build(now << 1 | 1, mid + 1, r);
	pushup(now);
}

void change(int now, int l, int r, int x, int val)
{
	if(l == r) {trmax[now] += val, trsum[now] += val; return ;} 
	int mid = (l + r) >> 1;
	if(x <= mid) change(now << 1, l, mid, x, val);
	else change(now << 1 | 1, mid + 1, r, x, val);
	pushup(now);
}

int askmax(int now, int l, int r, int x, int y)
{
	if(x <= l && r <= y) return trmax[now];
	int mid = (l + r) >> 1;
	if(y <= mid) return askmax(now << 1, l, mid, x, y);
	if(x > mid) return askmax(now << 1 | 1, mid + 1, r, x, y);
	return max(askmax(now << 1, l, mid, x, mid), askmax(now << 1 | 1, mid + 1, r, y, mid));
}

int asksum(int now, int l, int r, int x, int y)
{
	if(x <= l && r <= y) return trsum[now];
	int mid = (l + r) >> 1;
	if(y <= mid) return asksum(now << 1, l, mid, x, y);
	if(x > mid) return asksum(now << 1 | 1, mid + 1, r, x, y);
	return asksum(now << 1, l, mid, x, mid) + asksum(now << 1 | 1, mid + 1, r, y, mid);
}

int qmax(int x, int y)
{
	int ans = 0;
	while(top[x] != top[y])
	{
		if(dep[top[x]] < dep[top[y]]) swap(x, y);
		ans = max(ans, askmax(1, 1, n, id[top[x]], id[x]));
		x = fa[top[x]];
	}
	if(dep[x] > dep[y]) swap(x, y);
	ans = max(ans, askmax(1, 1, n, id[x], id[y]));
	return ans;
}

int qsum(int x, int y)
{
	int ans = 0;
	while(top[x] != top[y])
	{
		if(dep[top[x]] < dep[top[y]]) swap(x, y);
		ans = ans + asksum(1, 1, n, id[top[x]], id[x]);
		x = fa[top[x]];
	}
	if(dep[x] > dep[y]) swap(x, y);
	ans += asksum(1, 1, n, id[x], id[y]);
	return ans;
}

int main()
{
	std::ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	cin >> n;
	for(int i = 1; i < n; i++)
	{
		int x, y;
		cin >> x >> y;
		add_edge(x, y);
		add_edge(y, x); 
	}
	for(int i = 1; i <= n; i++) cin >> b[i];
	dfs1(1, 0); 
	cnt = 0;
	dfs2(1, 1);
	build(1, 1, n);
	cin >> q;
	while(q--)
	{
		char s[10];
		int x, y;
		cin >> s + 1;
		cin >> x >> y;
		if(s[1] == 'C') change(1, 1, n, id[x], y);
		else
		{
			if(s[2] == 'M') cout << qmax(x, y) << "\n";
			else cout << qsum(x, y) << "\n";
		}
	}
	
	return 0;
}
2023/8/7 20:16
加载中...