官方题解说的很清楚了,提供一个实现。
改了一年bug,过于菜了...
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&(-x))
#define REP(i, a, n) for(int i=a;i<=(n);i++)
#define IOS ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
const int maxn = 1e5 + 10;
const int N = 1e6 + 10;
const int M = 2e6 + 10;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const int mod2 = 998244353;
const int mod3 = 1e9 + 9;
const int hash1 = 131;
const int hash2 = 13331;
int tot;
int head[N], nxt[M], ver[M];
void addedge(int x, int y)
{
ver[++tot] = y, nxt[tot] = head[x], head[x] = tot;
}
ll ans[5005];
struct query
{
int k, op, id;
query(int k, int op, int id) : k(k), op(op), id(id)
{
//cout << " k == " << k << " op == " << op << " id == " << id << endl;
}
};
vector<query> q[N];
ll val[N];
int fa[N];
void dfs(int x, int pre)
{
fa[x] = pre;
for (int i = head[x]; i; i = nxt[i])
{
int y = ver[i];
if (y != pre)
dfs(y, x);
}
}
ll c[N];
void add(int x, ll val)
{
for (int i = x; i < N; i += lowbit(i))
c[i] += val;
}
ll ask(int x)
{
ll ans = 0;
for (int i = x; i > 0; i -= lowbit(i))
ans += c[i];
return ans;
}
void dfs2(int x, int dep)
{
for (int i = 0; i < q[x].size(); i++)
{
ll t = -q[x][i].op * (ask(q[x][i].k + dep) - ask(dep - 1));
ans[q[x][i].id] += t;
}
add(dep, val[x]);
for (int i = head[x]; i; i = nxt[i])
{
int y = ver[i];
if (y == fa[x])
continue;
dfs2(y, dep + 1);
}
for (int i = 0; i < q[x].size(); i++)
{
ll t = q[x][i].op * (ask(q[x][i].k + dep) - ask(dep - 1));
ans[q[x][i].id] += t;
}
}
int main()
{
IOS;
int n;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> val[i];
for (int i = 1; i < n; i++)
{
int u, v;
cin >> u >> v;
addedge(u, v);
addedge(v, u);
}
dfs(1, 0);
int m;
cin >> m;
for (int i = 1; i <= m; i++)
{
int v, k;
cin >> v >> k;
q[v].push_back(query(k, 1, i));
k--;
while (v != 1 && k >= 0)
{
if (k > 0)
q[v].push_back(query(k - 1, -1, i));
v = fa[v];
q[v].push_back(query(k, 1, i));
k--;
}
}
dfs2(1, 1);
for (int i = 1; i <= m; i++)
{
cout << ans[i] << endl;
}
return 0;
}