BZOJ4034【树链剖分】【线段树】

来源:互联网 发布:cnn tensorflow 编辑:程序博客网 时间:2024/05/14 00:38
/* I will wait for you */    #include <cstdio>  #include <cstdlib>  #include <cstring>  #include <cmath>  #include <ctime>  #include <algorithm>  #include <iostream>  #include <fstream>  #include <vector>  #include <queue>  #include <deque>  #include <set>  #include <map>  #include <string>  #define make(a,b) make_pair(a,b)  #define fi first  #define se second    using namespace std;    typedef long long ll;  typedef unsigned long long ull;  typedef pair<int, int> pii;  typedef map<int, int> mii;    const int maxn = 100010;  const int maxm = 1010;  const int maxs = 26;  const int inf = 0x3f3f3f3f;  const int P = 1000000007;  const double error = 1e-9;    inline ll read()  {      ll x = 0, f = 1; char ch = getchar();      while (ch > '9' || ch < '0' )          f = (ch == '-' ? -1 : 1), ch = getchar();      while (ch <= '9' && ch >= '0')          x = x * 10 + ch - '0', ch = getchar();      return f * x;  }    struct edge  {      int v, next;  } e[2 * maxn];    struct node  {      int l, r; ll sum, add;  } t[4 * maxn];    int n, m, cnt, dfn, per[maxn], fa[maxn], mx[maxn], pr[maxn],deep[maxn], size[maxn], pos[maxn], head[maxn];  void insert(int u, int v)  {      e[cnt] = (edge) {v, head[u]}, head[u] = cnt++;      e[cnt] = (edge) {u, head[v]}, head[v] = cnt++;  }    void dfs1(int u)  {      size[u] = 1;        for (int i = head[u]; i != -1; i = e[i].next) {          int v = e[i].v;          if (v != fa[u]) {              fa[v] = u, deep[v] = deep[u] + 1;              dfs1(v), size[u] += size[v];                if (size[v] > size[mx[u]])                  mx[u] = v;          }      }  }    void dfs2(int u, int p)  {      pos[u] = ++dfn, per[u] = p;        if (mx[u])          dfs2(mx[u], p);        for (int i = head[u]; i != -1; i = e[i].next) {          int v = e[i].v;          if (v != fa[u] && v != mx[u])              dfs2(v, v);      }  }  void build(int u, int l, int r)  {      t[u].l = l, t[u].r = r;            if (l != r) {          int mid = (l + r) / 2;            build(2 * u, l, mid);          build(2 * u + 1, mid + 1, r);      }  }  void maintain(int u){int l = t[u].l, r = t[u].r;t[u].sum = 0;if (r > l)t[u].sum = t[2 * u].sum + t[2 * u + 1].sum;t[u].sum += (r - l + 1) * t[u].add;}void add(int u, int x, int y, int c){int l = t[u].l, r = t[u].r;if (l >= x && r <= y)t[u].add += c;else {int mid = (l + r) / 2;if (x <= mid)add(2 * u, x, y, c);if (y > mid)add(2 * u + 1, x, y, c);}maintain(u);}ll query(int u, int x, int y, ll add){int l = t[u].l, r = t[u].r;if (l >= x && r <= y)return t[u].sum + (r - l + 1) * add;else {int mid = (l + r) / 2; ll ans = 0;if (x <= mid)ans += query(2 * u, x, y, add + t[u].add);if (y > mid)ans += query(2 * u + 1, x, y, add + t[u].add);return ans;}}ll query(int u){ll ans = 0;while (u) {ans += query(1, pos[per[u]], pos[u], 0);u = fa[per[u]];}return ans;}int main()  {      n = read(), m = read(), build(1, 1, n);        memset(head, -1, sizeof head);          for (int i = 1; i <= n; i++)    pr[i] = read();        for (int i = 1; i < n; i++) {          int u = read(), v = read();          insert(u, v);      }        dfs1(1), dfs2(1, 1);        for (int i = 1; i <= n; i++)    add(1, pos[i], pos[i], pr[i]);        for (int i = 1; i <= m; i++) {    int t = read();        if (t == 1) {    int u = read(), c = read();    add(1, pos[u], pos[u], c);    }        if (t == 2) {    int u = read(), c = read();    add(1, pos[u], pos[u] + size[u] - 1, c);    }        if (t == 3) {    int u = read();    printf("%lld\n", query(u));    }    }      return 0;  }  
0 0