社区讨论

如何极致地压缩空间?

学术版参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mk56ipz2
此快照首次捕获于
2026/01/08 16:22
上个月
此快照最后确认于
2026/01/10 21:55
上个月
查看原帖
HDU - 6162是一道恶心的题目,64MB的空间对于主席树选手是极度不友好的,但我看到有人用主席树过了,所以,RT
CPP
#include <bits/stdc++.h>
using namespace std;
#define I cin>>
#define O cout<<
#define ll long long
const int N = 1e5 + 5;
vector<int> edge[N];
int c[N], n, m, s1, s2, s3, s4;
int fa[N], dep[N], siz[N], son[N];
int dfn[N], sum[N], top[N], idx;
void dfs1(int rt, int f) {
	fa[rt] = f;
	dep[rt] = dep[f] + 1;
	siz[rt] = 1;
	son[rt] = 0;
	int mx = 0;
	for (int it : edge[rt]) {
		if (it == f) continue;
		dfs1(it, rt);
		siz[rt] += siz[it];
		if (siz[it] > mx) {
			mx = siz[it];
			son[rt] = it;
		}
	}
}
void dfs2(int rt, int tp) {
	dfn[rt] = ++idx;
	sum[idx] = rt;
	top[rt] = tp;
	if (son[rt]) dfs2(son[rt], tp);
	for (int it : edge[rt]) {
		if (it != fa[rt] && it != son[rt]) dfs2(it, it);
	}
}
struct Node {
	int lc, rc;
	ll sum;
} tree[N * 40];
int root[N], tot;
void edit(int &rt, int x, int l, int r, int pos, int k) {
	rt = ++tot;
	tree[rt] = tree[x];
	tree[rt].sum += k;
	if (l == r) return;
	int mid = (l + r) >> 1;
	if (pos <= mid) edit(tree[rt].lc, tree[x].lc, l, mid, pos, k);
	else edit(tree[rt].rc, tree[x].rc, mid + 1, r, pos, k);
}
ll query(int x, int y, int l, int r, int dl, int dr) {
	if (dl <= l && r <= dr) return tree[x].sum - tree[y].sum;
	int mid = (l + r) >> 1;
	ll res = 0;
	if (dl <= mid) res += query(tree[x].lc, tree[y].lc, l, mid, dl, dr);
	if (dr > mid) res += query(tree[x].rc, tree[y].rc, mid + 1, r, dl, dr);
	return res;
}
vector<int> vals;
int get(int x) {
	return lower_bound(vals.begin(), vals.end(), x) - vals.begin() + 1;
}
int main() {
//	freopen("gift.in", "r", stdin);
//	freopen("gift.out", "w", stdout);
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	while (I n >> m) {
		for(int i=1;i<=n;i++) edge[i].clear();
		vals.clear();
		for(int i=1;i<=40*n;i++) tree[i]={0,0,0};
		vector<tuple<int, int, int, int> > quy(m);
		for (int i = 1; i <= n; i++) {
			I c[i];
			vals.push_back(c[i]);
		}
		for (int i = 1; i < n; i++) {
			I s1 >> s2;
			edge[s1].push_back(s2);
			edge[s2].push_back(s1);
		}
		dfs1(1, 1);
		dfs2(1, 1);
		for (int i = 0; i < m; i++) {
			I s1 >> s2 >> s3 >> s4;
			quy[i] = {s1, s2, s3, s4};
			vals.push_back(s3);
			vals.push_back(s4);
		}
		sort(vals.begin(), vals.end());
		vals.erase(unique(vals.begin(), vals.end()), vals.end());
		int V = vals.size();
		for (int i = 1; i <= n; i++) {
			int pos = get(c[sum[i]]);
			edit(root[i], root[i - 1], 1, V, pos, c[sum[i]]);
		}
		for (int i = 0; i < m; i++) {
			int s = get<0>(quy[i]), t = get<1>(quy[i]);
			int a = get<2>(quy[i]), b = get<3>(quy[i]);
			int dl = lower_bound(vals.begin(), vals.end(), a) - vals.begin() + 1;
			int dr = upper_bound(vals.begin(), vals.end(), b) - vals.begin();
			ll ans = 0;
			if (dl <= dr) {
				int u = s, k = t;
				while (top[u] != top[k]) {
					if (dep[top[u]] < dep[top[k]]) swap(u, k);
					int L = dfn[top[u]], R = dfn[u];
					ans += query(root[R], root[L - 1], 1, V, dl, dr);
					u = fa[top[u]];
				}
				if (dep[u] > dep[k]) swap(u, k);
				int L = dfn[u], R = dfn[k];
				ans += query(root[R], root[L - 1], 1, V, dl, dr);
			}
			O ans << (i == m - 1 ? "\n" : " ");
		}
	}
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...