トピックリンク:ポイント私はああ╭(╯^╰)╮
効果の件名:
木、二つの操作:
①:ポイント
置きます
キノコ
②:V $出発点となる
すべてのキノコ収集の運転コスト開始各計算後に
最短経路上の右側の第一の端部に、出発点としてキノコのコストを収集します
問題解決のアイデア:
ポイントを計算
三つの部分で計算の答え、
重い息子サブツリーすべての答え
これらのキノコにあります
を犠牲にして、このエッジ右側の重い息子に
ので、各更新点
ときのメンテナンス
重鎖のルートにキノコの数
光のすべての息子たちへの答えどこのサブツリー
の最初のステップではこの部分、とき暴力統計ストランド為替の重症度
父コラージュ権に対する答えを犠牲に
キノコの合計数によって、
キノコと2例に
コア:軽鎖および重鎖分割アプリケーション
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
#define fi first
#define se second
using namespace std;
typedef long long ll;
using pii = pair <ll,ll>;
const int maxn = 1e6 + 5;
int n, q, dep[maxn], fa[maxn], fv[maxn], size[maxn];
ll sum, t[maxn<<2], lz[maxn<<2], cnt[maxn];
int dfn[maxn], id[maxn], tot, son[maxn], top[maxn];
vector <pii> g[maxn];
pii ans[maxn];
void dfs1(int u, int f, int de) {
dep[u] = de, fa[u] = f, size[u] = 1;
for(auto tmp : g[u]) {
int v = tmp.fi;
int w = tmp.se;
if(v == f) continue;
dfs1(v, u, de+1);
fv[v] = w;
size[u] += size[v];
if(size[son[u]] < size[v]) son[u] = v;
}
}
void dfs2(int u, int tp) {
top[u] = tp, dfn[++tot] = u, id[u] = tot;
if(son[u]) dfs2(son[u], tp);
for(auto tmp : g[u]) {
int v = tmp.fi;
if(v == fa[u]) continue;
if(v == son[u]) continue;
dfs2(v, v);
}
}
void pushdown(int rt) {
if(lz[rt]) {
t[rt<<1] += lz[rt];
t[rt<<1|1] += lz[rt];
lz[rt<<1] += lz[rt];
lz[rt<<1|1] += lz[rt];
lz[rt] = 0;
}
}
void update(ll x, int L, int R, int l, int r, int rt) {
if(l>R || r<L) return;
if(l>=L && r<=R) {
t[rt] += x;
lz[rt] += x;
return;
}
pushdown(rt);
int mid = l + r >> 1;
update(x, L, R, l, mid, rt<<1);
update(x, L, R, mid+1, r, rt<<1|1);
t[rt] = t[rt<<1] + t[rt<<1|1];
}
ll query(int pos, int l, int r, int rt) {
if(pos>r || pos<l) return 0;
if(l == r) return t[rt];
pushdown(rt);
int mid = l + r >> 1; ll ret = 0;
ret += query(pos, l, mid, rt<<1);
ret += query(pos, mid+1, r, rt<<1|1);
return ret;
}
void gao(int u, int x) {
while(u) {
update(x, id[top[u]], id[u], 1, n, 1);
u = top[u];
ans[fa[u]].fi += 1ll * x * fv[u];
ans[fa[u]].se += x;
u = fa[u];
}
}
void solve(int u) {
ll res = 0, num = query(id[son[u]], 1, n, 1);
res += 1ll * num * fv[son[u]];
res += 1ll * (sum - cnt[u] - num - ans[u].se) * fv[u];
res += ans[u].fi;
printf("%lld\n", res);
}
int main() {
scanf("%d", &n);
for(int i=1, u, v, w; i<n; i++) {
scanf("%d%d%d", &u, &v, &w);
g[u].push_back({v, w});
g[v].push_back({u, w});
}
dfs1(1, 0, 1);
dfs2(1, 1);
scanf("%d", &q);
int op, v, x, rt = 1;
while(q--) {
scanf("%d", &op);
if(op == 1) {
scanf("%d%d", &v, &x);
sum += x;
cnt[v] += x;
gao(v, x);
} else scanf("%d", &rt);
solve(rt);
}
}