// compile: make data // run: ./data < data.in #include <bits/stdc++.h> using namespace std; #pragma GCC optimize("O3,unroll-loops") #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") #ifdef LOCAL #include <debug/codeforces.h> #define debug(x...) _debug_print(#x, x); #define Debug(x...) _debug_print_format(#x, x); #else #define debug(x...) #define Debug(x...) #endif template<typename...Args> void print_(Args...args){((cout<<args<<" "),...)<<endl;} #define VI vector<int> #define VII vector<vector<int>> #define VIII vector<vector<vector<int>>> #define rep(i,a,b) for(int i=(a);i<(int)(b);++i) #define sz(v) ((int)(v).size()) #define print(...) print_(__VA_ARGS__); #define FIND(a, x) ((find(a.begin(),a.end(),(x))!=a.end())?1:0) #define cmin(x,...) x=min({(x), __VA_ARGS__}) #define cmax(x,...) x=max({(x), __VA_ARGS__}) #define INTMAX (int)(9223372036854775807) #define INF (int)(1152921504606846976) #define NaN (int)(0x8b88e1d0595d51d1) #define double long double #define int long long #define MAXN 200010 struct tree { int n; vector<vector<int>> e; struct node { vector<node*> ch; node* parent = nullptr; int size, depth, val, sum; }; vector<node> vertex; node *root; tree(int V) { n = V; e.resize(n); vertex.resize(n); } void setv(vector<int> &a) { rep(i, 0, n) vertex[i].val = a[i]; } void add_edge(int u, int v) { e[u].push_back(v), e[v].push_back(u); } int ind(node *x) {return x - &vertex[0]; } void build(int rt = 0) { function<void(int, int)> dfs = [&](int u, int pre) { vertex[u].size = 1; vertex[u].depth = u==ind(root) ? 0 : vertex[u].parent->depth + 1; vertex[u].sum = u==ind(root) ? vertex[u].val : vertex[u].parent->sum + vertex[u].val; for (int v: e[u]) { if (v == pre) continue; vertex[u].ch.push_back(&vertex[v]); vertex[v].parent = &vertex[u]; dfs(v, u); vertex[u].size += vertex[v].size; } }; root = &vertex[rt]; dfs(rt, -1); } pair<vector<int>, vector<pair<int, int>>> dfsorder() { vector<int> order; vector<pair<int, int>> ts(n); int cnt = 0; function<void(node*)> dfs = [&](node *x) { ts[ind(x)].first = cnt++; order.push_back(ind(x)); for (auto y: x->ch) dfs(y); order.push_back(ind(x)); ts[ind(x)].second = cnt++; }; dfs(root); return {order, ts}; } void graphviz_dump(int plus = 0, string filename = "graph.dot") { FILE *f = fopen(filename.c_str(), "w"); fprintf(f, "digraph Tree {\n"); rep(i, 0, n) { node *x = &vertex[i]; fprintf(f, " %lld;\n"); } rep(i, 0, n) { node *x = &vertex[i]; for (auto y: x->ch) { fprintf(f, " %ld -> %ld;\n", x - &vertex[0], y - &vertex[0]); } } fprintf(f, "}\n"); } }; struct bitree { int n; vector<vector<int>> c; vector<int> sum; bitree(vector<int> &a) { n = sz(a); sum.push_back(0); rep(i, 0, n) sum.push_back(sum[i] + a[i]); c.resize(2, vector<int>(n+1, 0)); } int lowbit(int x) {return x & (-x); } void add(int b, int x, int y) {for (; x <= n; x += lowbit(x)) c[b][x] += y; } int get(int b, int x) {int ans = 0; for (; x; x -= lowbit(x)) ans += c[b][x]; return ans; } void modify(int p, int k) {modify(p, p, k); } void modify(int l, int r, int k) {add(0, l+1, k); add(0, r+2, -k); add(1, l+1, (l+1)*k); add(1, r+2, -(r+2)*k); } int query(int p) {return query(p, p); } int query(int l, int r) {int ans = sum[r+1] + (r+2)*get(0, r+1) - get(1, r+1); ans -= sum[l] + (l+1)*get(0, l) - get(1, l); return ans; } }; int32_t main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int n, q; cin >> n >> q; vector<int> a(n); rep(i, 0, n) cin >> a[i]; tree g(n); g.setv(a); rep(i, 0, n-1) { int u, v; cin >> u >> v; --u, --v; g.add_edge(u, v); } g.build(0); auto [order, ts] = g.dfsorder(); rep(i, 0, 2*n) order[i] = g.vertex[order[i]].sum; bitree t(order); while (q--) { int op; cin >> op; if (op == 1) { int s, x; cin >> s >> x; --s; t.modify(ts[s].first, ts[s].second, x-a[s]); a[s] = x; } else if (op == 2) { int s; cin >> s; --s; cout << t.query(ts[s].first) << '\n'; } } return 0; }
No Comments