求助点分树神秘TLE
查看原帖
求助点分树神秘TLE
727411
invisible_person楼主2023/1/7 23:13

感觉应该是某个地方写挂了,A 5 个 T 5 个

#include <bits/stdc++.h>
#define int long long
#define chk_die printf("ALIVE\n")
using namespace std;

int read() {
	int s = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9')
		f = (ch == '-' ? -1 : 1), ch = getchar();
	while (ch >= '0' && ch <= '9')
		s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
	return s * f;
}

#define N 100005
#define M 200005

int n, m, a[N];
int to[M], nxt[M], head[N], tot = 0;

void add(int u, int v) {
	to[++tot] = v, nxt[tot] = head[u], head[u] = tot;
}

int d[N], sz[N], ht, Minp;
bool f[N];

void H(int p, int fa, int SZ) {
	int maxp = 0; sz[p] = 1;
	for (int i = head[p]; i; i = nxt[i])
		if (to[i] != fa && !f[to[i]])
			H(to[i], p, SZ), sz[p] += sz[to[i]], maxp = max(maxp, sz[to[i]]);
	maxp = max(maxp, SZ - sz[p]);
	if (maxp < Minp)
		Minp = maxp, ht = p;
}

int dep[1000005], fa[1000005];

int son[1000005] = {0}, top[1000005];
int dfn[1000005], rnk[1000005], tim = 0;

void pre(int p) {
	sz[p] = 1, dep[p] = dep[fa[p]] + 1;
	for (int i = head[p]; i; i = nxt[i])
		if (to[i] != fa[p]) {
			fa[to[i]] = p, pre(to[i]), sz[p] += sz[to[i]];
			if (!son[p] || sz[to[i]] > sz[son[p]])
				son[p] = to[i];
		}
}

void cut(int p, int tp) {
	top[p] = tp, dfn[p] = ++tim, rnk[tim] = p;
	if (son[p])
		cut(son[p], tp);
	for (int i = head[p]; i; i = nxt[i])
		if (to[i] != fa[p] && to[i] != son[p])
			cut(to[i], to[i]);
}

int lca(int u, int v) {
	if (top[u] == top[v])
		return dep[u] > dep[v] ? v : u;
	return dep[top[u]] > dep[top[v]] ? lca(fa[top[u]], v) : lca(fa[top[v]], u);
}

int dis(int x, int y) {
	int l = lca(x, y);
	return dep[x] + dep[y] - 2 * dep[l];
}

struct DTree {
	vector<int> e[N];
	int fa[N] = {0};
	void add(int u, int v) {e[u].push_back(v), fa[v] = u;}
	int Divid(int p, int SZ) {
		Minp = 1e9, H(p, 0, SZ);
		int rt = ht;
		H(rt, 0, SZ), f[rt] = true;
		for (int i = head[rt]; i; i = nxt[i])
			if (!f[to[i]])
				add(rt, Divid(to[i], sz[to[i]]));
		return rt;
	}
	struct BIT {
		unordered_map<int, int> sum;
		int MAX = 100000, cnt0 = 0;
		#define lb(x) (x & (-x))
		void mdf(int x, int v) {
			if (!x) {
				cnt0 += v;
				return ;
			}
			while (x <= MAX)
				sum[x] += v, x += lb(x);
		}
		int qry(int x) {
			int res = cnt0;
			while (x)
				res += sum[x], x -= lb(x);
			return res;
		}
	} t[N], tf[N];
	void mdf(int p, int d, int v, int pos) {
		t[p].mdf(d, v);
		if (fa[p]) {
			d = dis(pos, fa[p]);
			tf[p].mdf(d, v), mdf(fa[p], d, v, pos);
		}
	}
	void mdf(int x, int v) {
		mdf(x, 0, v - a[x], x), a[x] = v;
	}
	int qry(int x, int k) {
		int ans = t[x].qry(k), y = x;
		while (fa[x]) {
			int cnt = dis(y, fa[x]);
			if (cnt <= k)
				ans += t[fa[x]].qry(k - cnt) - tf[x].qry(k - cnt);
			x = fa[x];
		}
		return ans;
	}
} dt;

signed main() {
	n = read(), m = read();
	for (int i = 1; i <= n; i++)
		a[i] = read();
	for (int i = 1; i < n; i++) {
		int u = read(), v = read();
		add(u, v), add(v, u);
	}
	pre(1), cut(1, 1), dt.Divid(1, n);
	for (int i = 1; i <= n; i++)
		dt.mdf(i, 0, a[i], i);
	int lst = 0;
	while (m--) {
		int op = read();
		if (!op) {
			int x = read() ^ lst, k = read() ^ lst;
			printf("%lld\n", lst = dt.qry(x, k));
		}
		else {
			int x = read() ^ lst, y = read() ^ lst;
			dt.mdf(x, y);
		}
	}
	return 0;
}
2023/1/7 23:13
加载中...