社区讨论
如何极致地压缩空间?
学术版参与者 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 条回复,欢迎继续交流。
正在加载回复...