1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
#include <bits/stdc++.h> using namespace std;
#define EmiliaMyWife ios::sync_with_stdio(0); cin.tie(NULL); using ll = int64_t; using ull = uint64_t; using ld = long double; using uint = uint32_t; const double EPS = 1e-8; const int INF = 0x3F3F3F3F; const ll LINF = 4611686018427387903; const int MOD = 1e9+7;
const int N = 1e5 + 25;
vector<pair<int, int>> edge[N]; int pa[N], sz[N], cnt[N]; ll dis[N], no[N]; vector<ll> pa_dis[N]; bool vis[N], has[N];
int dfs(int u, int p) { sz[u] = 1; for(const auto &w : edge[u]) if(w.first != p && !vis[w.first]) { dfs(w.first, u); sz[u] += sz[w.first]; } return sz[u]; } int centroid(int u, int p, int n) { for(const auto &w : edge[u]) if(!vis[w.first] && w.first != p && sz[w.first] > n / 2) return centroid(w.first, u, n); return u; } void caldis(int u, int p, ll d) { pa_dis[u].push_back(d); for(const auto &w : edge[u]) if(!vis[w.first] && w.first != p) caldis(w.first, u, d + w.second); } void cd(int u, int p) { int n = dfs(u, u); u = centroid(u, u, n); vis[u] = 1; pa[u] = p; caldis(u, u, 0); for(const auto &w : edge[u]) { if(vis[w.first]) continue; cd(w.first, u); } } void edt(int u) { int x = u; for(int h = 0; ~u; u = pa[u], h++) { cnt[u]++; dis[u] += pa_dis[x][h]; if(h < pa_dis[x].size()) no[u] += pa_dis[x][h + 1]; } } ll query(int u) { ll res = 0, curd = 0; int curcnt = 0, x = u; for(int h = 0; ~u; u = pa[u], h++) { res += (dis[u] - curd) + (cnt[u] - curcnt) * pa_dis[x][h]; curcnt = cnt[u]; curd = no[u]; } return res; }
signed main() { EmiliaMyWife int n, q; cin >> n >> q; for(int i = 1, a, b, c; i < n; i++) { cin >> a >> b >> c; edge[a].push_back({b, c}); edge[b].push_back({a, c}); }
cd(0, -1); for(int i = 0; i < n; i++) reverse(pa_dis[i].begin(), pa_dis[i].end());
int t, x; while(q--) { cin >> t >> x; if(t == 1) { if(has[x]) continue; has[x] = 1; edt(x); } else cout << query(x) << '\n'; } }
|