EntropyIncreaser

BZOJ3730 震波

Feb 19th, 2018
298
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.80 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cstring>
  3.  
  4. #include <algorithm>
  5.  
  6. #define LOG(FMT...) // fprintf(stderr, FMT)
  7.  
  8. struct fenwick {
  9.     int n;
  10.     int* fw;
  11.  
  12.     void set(int n);
  13.     void change(int k, int x);
  14.     int query(int k) const;
  15. };
  16.  
  17. struct edge {
  18.     int v;
  19.     edge* next;
  20. };
  21.  
  22. const int N = 100010, LGN = 20;
  23.  
  24. int n, ql, qr;
  25. int val[N], q[N], sum[N], maxsum[N], divcnt[N], prt[N], dep[N], maxdep[N];
  26. int divrt[N][LGN], divsprt[N][LGN], divdep[N][LGN];
  27. fenwick divfw[N][LGN];
  28. bool cut[N], vis[N];
  29. edge* g[N];
  30.  
  31. int low_bit(int x);
  32. void add_edge(int u, int v);
  33. void divide(int u);
  34. void bfs(int u);
  35.  
  36. int main() {
  37. //  freopen("test.err", "w", stderr);
  38.     int m;
  39.     scanf("%d%d", &n, &m);
  40.     for (int i = 1; i <= n; ++i)
  41.         scanf("%d", &val[i]);
  42.     for (int rep = 1; rep < n; ++rep) {
  43.         int u, v;
  44.         scanf("%d%d", &u, &v);
  45.         add_edge(u, v);
  46.         add_edge(v, u);
  47.     }
  48.     divide(1);
  49.     int last = 0;
  50.     while (m--) {
  51.         int op, u, x;
  52.         scanf("%d%d%d", &op, &u, &x);
  53.         u ^= last;
  54.         x ^= last;
  55.         if (op == 0) {
  56.             last = 0;
  57.             for (int i = 0; i < divcnt[u] - 1; ++i) {
  58.                 if (divdep[u][i] > x)
  59.                     continue;
  60.                 last += val[divrt[u][i]];
  61.                 last += divfw[divrt[u][i]][i].query(x - divdep[u][i]);
  62.                 last -= divfw[divsprt[u][i]][i].query(x - divdep[u][i]);
  63.             }
  64.             last += val[u];
  65.             last += divfw[u][divcnt[u] - 1].query(x);
  66.             printf("%d\n", last);
  67.         } else {
  68.             int delt = x - val[u];
  69.             val[u] = x;
  70.             for (int i = 0; i < divcnt[u] - 1; ++i) {
  71.                 divfw[divrt[u][i]][i].change(divdep[u][i], delt);
  72.                 divfw[divsprt[u][i]][i].change(divdep[u][i], delt);
  73.             }
  74.         }
  75.     }
  76.     return 0;
  77. }
  78.  
  79. void bfs(int u) {
  80.     ql = 0;
  81.     qr = 1;
  82.     q[0] = u;
  83.     while (ql < qr) {
  84.         u = q[ql++];
  85.         vis[u] = true;
  86.         for (edge* p = g[u]; p; p = p->next)
  87.             if (!vis[p->v] && !cut[p->v]) {
  88.                 q[qr++] = p->v;
  89.             }
  90.     }
  91. }
  92.  
  93. void divide(int u) {
  94.     bfs(u);
  95.     int div = q[qr - 1];
  96.     for (int i = qr - 1; i >= 0; --i) {
  97.         u = q[i];
  98.         vis[u] = false;
  99.         sum[u] = 1;
  100.         maxsum[u] = 0;
  101.         for (edge* p = g[u]; p; p = p->next)
  102.             if (!vis[p->v] && !cut[p->v]) {
  103.                 sum[u] += sum[p->v];
  104.                 maxsum[u] = std::max(maxsum[u], sum[p->v]);
  105.             }
  106.         maxsum[u] = std::max(maxsum[u], qr - sum[u]);
  107.         if (maxsum[u] < maxsum[div])
  108.             div = u;
  109.     }
  110.     cut[div] = true;
  111.     bfs(div);
  112.     LOG("DIV %d\n", div);
  113.     int cd = divcnt[div];
  114.     ++divcnt[div];
  115.     if (cd > 18) {
  116.         LOG("ERR\n");
  117.     }
  118.     vis[div] = false;
  119.     divrt[div][cd] = div;
  120.     for (edge* p = g[div]; p; p = p->next)
  121.         if (!cut[p->v]) {
  122.             divdep[p->v][cd] = 1;
  123.             divsprt[p->v][cd] = p->v;
  124.         }
  125.     for (int i = 1; i < qr; ++i) {
  126.         u = q[i];
  127.         ++divcnt[u];
  128.         vis[u] = false;
  129.         divrt[u][cd] = div;
  130.         maxdep[divsprt[u][cd]] = divdep[u][cd];
  131.         for (edge* p = g[u]; p; p = p->next)
  132.             if (!cut[p->v] && vis[p->v]) {
  133.                 divsprt[p->v][cd] = divsprt[u][cd];
  134.                 divdep[p->v][cd] = divdep[u][cd] + 1;
  135.             }
  136.     }
  137.     divfw[div][cd].set(divdep[q[qr - 1]][cd]);
  138.     for (int i = 1; i < qr; ++i) {
  139.         u = q[i];
  140.         if (divdep[u][cd] == 1) {
  141.             LOG("%d SET %d\n", u, maxdep[u]);
  142.             divfw[u][cd].set(maxdep[u]);
  143.         }
  144.         divfw[div][cd].change(divdep[u][cd], val[u]);
  145.         divfw[divsprt[u][cd]][cd].change(divdep[u][cd], val[u]);
  146.     }
  147.     for (edge* p = g[div]; p; p = p->next) {
  148.         if (!cut[p->v])
  149.             divide(p->v);
  150.     }
  151. }
  152.  
  153. void add_edge(int u, int v) {
  154.     static edge pool[N * 2];
  155.     static edge* p = pool;
  156.     p->v = v;
  157.     p->next = g[u];
  158.     g[u] = p;
  159.     ++p;
  160. }
  161.  
  162. void fenwick::set(int n) {
  163.     static int pool[N * LGN * 2];
  164.     static int* top = pool;
  165. //  if (top - pool > N * LGN)
  166. //      LOG("SET %ld %d\n", top - pool, N * LGN * 2);
  167.     fenwick::n = n;
  168.     fw = top - 1;
  169.     top += n;
  170. }
  171.  
  172. void fenwick::change(int k, int x) {
  173.     for (; k <= n; k += low_bit(k))
  174.         fw[k] += x;
  175. }
  176.  
  177. int fenwick::query(int k) const {
  178.     int ret = 0;
  179.     if (k > n)
  180.         k = n;
  181.     for (; k; k -= low_bit(k)) {
  182.         ret += fw[k];
  183.     }
  184.     return ret;
  185. }
  186.  
  187. int low_bit(int x) {
  188.     return x & -x;
  189. }
Advertisement
Add Comment
Please, Sign In to add comment