题意
首先观察发现
如果没有加值操作u级父亲 = (u == 0) ? 自己 : 父亲的(u-1)级父亲
最后考虑加值操作
AC代码
#include <bits/stdc++.h>
#define maxn 500005
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
struct oper {
ll high, low, val;
};
vector<pll> downop[maxn];
ll levval[maxn], a[maxn], ans[maxn];
vector<ll> G[maxn];
vector<oper> up[maxn];
char type[maxn];
ll ind[maxn], val[maxn];
ll n;
ll inv[maxn];
vector<ll> path;
void dfsup(ll u, ll fa, ll lev) {
auto it = find(G[u].begin(), G[u].end(), fa);
if (it != G[u].end()) G[u].erase(it);
path.push_back(u);
for (auto p : up[u]) {
ll h = max(0LL, lev - p.high);
downop[path[h]].push_back(pll(p.low, p.val));
}
for (auto v : G[u]) {
dfsup(v, u, lev + 1);
}
path.pop_back();
}
ll mul = 1, divi = 1;
void dfsdown(ll u, ll lev) {
for (auto p : downop[u]) {
ll h = lev + p.first;
if (h < n) levval[h] = (levval[h] + p.second * mul) % MOD;
}
ans[u] = levval[lev] * divi % MOD;
for (auto v : G[u]) {
mul = mul * G[u].size() % MOD;
divi = divi * inv[G[u].size()] % MOD;
dfsdown(v, lev + 1);
mul = mul * inv[G[u].size()] % MOD;
divi = divi * G[u].size() % MOD;
}
for (auto p : downop[u]) {
ll h = lev + p.first;
if (h < n) {
levval[h] = (levval[h] - p.second * mul) % MOD;
if (levval[h] < 0) levval[h] += MOD;
}
}
}
int main()
{
// freopen("G.in", "r", stdin);
cin.tie(0)->sync_with_stdio(0);
// inv
inv[1] = 1;
for (ll i = 2; i < maxn; ++i) {
inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
}
cin >> n;
for (ll i = 1; i <= n; ++i) {
cin >> a[i];
}
ll u, v;
for (ll i = 1; i < n; ++i) {
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
ll q;
cin >> q;
for (ll i = 1; i <= q; ++i) {
cin >> type[i];
if (type[i] == '+') {
cin >> ind[i] >> val[i];
}
}
ll high = 0, cur = 0;
for (ll i = q; i > 0; --i) {
if (type[i] == '^') cur--;
else if (type[i] == 'v') cur++;
high = max(high, cur);
if (type[i] == '+') {
up[ind[i]].push_back(oper{high - cur, high, val[i]});
}
}
for (ll i = 1; i <= n; ++i) {
up[i].push_back(oper{high - cur, high, a[i]});
}
dfsup(1, -1, 0);
dfsdown(1, 0);
for (ll i = 1; i <= n; ++i) {
cout << ans[i] << ' ';
}
return 0;
}