mxqz
查看原帖
mxqz
421781
liuzimingc楼主2024/9/9 16:57

RT。看了 114514 光年也看不出来哪里错了。。。

#include <bits/stdc++.h>
 
using namespace std;

namespace liuzimingc {
#define endl '\n'
#define mid ((t[p].l + t[p].r) >> 1)
#define lc (p << 1)
#define rc (p << 1 | 1) 
const int N = 2e5 + 5, M = 55, X = 1 << 16, Y = (1 << 30) - 1 + (1 << 30);

int n, m, A, B, Q, q, fa[N], dfn[N], to[N], cnt, dep[N], top[N];
vector<int> e[N];
int siz[N], son[N];

int getint() {
	A = ((A ^ B) + (B / X) + 1ll * B * X) & Y;
	B = ((A ^ B) + (A / X) + 1ll * A * X) & Y;
	return (A ^ B) % Q;
}

struct knapsack {
	int a[M], t[M];
	
	void clear() {
		memset(a, 0, sizeof(a));
	}
	
	void gen() {
		for (int i = 1; i <= m; i++) a[i] = getint();
		sort(a + 1, a + 1 + m);
	}
	
	void get_mx(knapsack b) {
		for (int i = 1; i <= m; i++) a[i] = max(a[i], b.a[i]); 
	}
	
	void merge(knapsack b) {
		memset(t, 0, sizeof(t));
		for (int i = 0; i <= m; i++)
			for (int j = 0; i + j <= m; j++)
				t[i + j] = max(t[i + j], a[i] + b.a[j]);
		for (int i = 0; i <= m; i++) a[i] = t[i];
	}
} a[N];

struct tree {
	int l, r;
	knapsack mx, v;
} t[N << 2];

void push_up(int p) {
	t[p].mx.clear();
	t[p].mx.get_mx(t[lc].mx);
	t[p].mx.get_mx(t[rc].mx);
	t[p].v.clear();
	t[p].v.merge(t[lc].v);
	t[p].v.merge(t[rc].v);
}

void build(int p, int l, int r) {
	t[p].l = l, t[p].r = r;
	if (l == r) {
		t[p].v = t[p].mx = a[t[p].l];
		return;
	}
	build(lc, l, mid);
	build(rc, mid + 1, r);
	push_up(p);
}

void update(int p, int x) {
	if (t[p].l == t[p].r) {
		t[p].mx.gen();
		t[p].v = t[p].mx;
		return;
	}
	if (x <= mid) update(lc, x);
	else update(rc, x);
	push_up(p); 
}

knapsack ask_mx(int p, int l, int r) {
	if (l <= t[p].l && t[p].r <= r) return t[p].mx;
	knapsack ans;
	ans.clear();
	if (l <= mid) ans.get_mx(ask_mx(lc, l, r));
	if (r > mid) ans.get_mx(ask_mx(rc, l, r));
	return ans;
}

knapsack ask_v(int p, int l, int r) {
	if (l <= t[p].l && t[p].r <= r) return t[p].v;
	knapsack ans;
	ans.clear();
	if (l <= mid) ans.merge(ask_v(lc, l, r));
	if (r > mid) ans.merge(ask_v(rc, l, r));
	return ans;
}

void dfs1(int u) {
	siz[u] = 1;
	for (int v : e[u]) {
		dep[v] = dep[u] + 1;
		dfs1(v);
		siz[u] += siz[v];
		if (siz[v] > siz[son[u]]) son[u] = v;
	}
}

void dfs2(int u, int t) {
	to[dfn[u] = ++cnt] = u;
	top[u] = t;
	if (!son[u]) return;
	dfs2(son[u], t);
	for (int v : e[u]) {
		if (v == son[u]) continue;
		dfs2(v, v);
	}
}

knapsack ask_chain(int u, int v) { // v is the ancestor of u
	if (u == v) return ask_mx(1, dfn[u], dfn[u]);
	u = fa[u];
	knapsack ans;
	ans.clear();
	while (top[u] != top[v]) {
		ans.get_mx(ask_mx(1, dfn[top[u]], dfn[u]));
		u = fa[top[u]]; 
	}
	ans.get_mx(ask_mx(1, dfn[v], dfn[u]));
	return ans;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> n >> m >> A >> B >> Q;
	for (int i = 2; i <= n; i++) {
		cin >> fa[i];
		e[fa[i]].push_back(i);
	}
	dfs1(1);
	dfs2(1, 1);
	for (int i = 1; i <= n; i++) a[to[i]].gen();
	build(1, 1, n);
	cin >> q;
	while (q--) {
		int op;
		cin >> op;
		if (!op) {
			int x;
			cin >> x;
			update(1, dfn[x]);
		}
		else {
			int u, v;
			cin >> u >> v;
			knapsack ans = ask_chain(u, v);
			ans.merge(ask_v(1, dfn[u], dfn[u] + siz[u] - 1));
			cout << ans.a[m] << endl;
		}
	}
	return 0;
}
#undef int
} // namespace liuzimingc
    
int main() {
	liuzimingc::main();
	return 0;
}
2024/9/9 16:57
加载中...