Advertisement
Guest User

Untitled

a guest
Jul 18th, 2019
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.74 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. const int MAX_N = 100000;
  6. int segtree[4 * MAX_N];
  7.  
  8. void segtreeupd(int idx, int l, int r, int i, int v) {
  9.   if(l == r) segtree[idx] = v;
  10.   else {
  11.     int m = (l+r)/2;
  12.     if(i <= m) segtreeupd(2*idx, l, m, i, v);
  13.     else segtreeupd(2*idx+1, m+1, r, i, v);
  14.     segtree[idx] = segtree[2*idx] ^ segtree[2*idx+1];
  15.   }
  16. }
  17. void segtreeupd(int i, int v) {
  18.   segtreeupd(1, 0, MAX_N-1, i, v);
  19. }
  20.  
  21. int segtreeqry(int idx, int l, int r, int lhs, int rhs) {
  22.   if(l >= lhs && r <= rhs) return segtree[idx];
  23.   int ret = 0;
  24.   int m = (l+r)/2;
  25.   if(m >= lhs) ret ^= segtreeqry(2*idx, l, m, lhs, rhs);
  26.   if(m+1 <= rhs) ret ^= segtreeqry(2*idx+1, m+1, r, lhs, rhs);
  27.   return ret;
  28. }
  29. int segtreeqry(int l, int r) {
  30.   return segtreeqry(1, 0, MAX_N-1, l, r);
  31. }
  32.  
  33. const int MAX_D = 17;
  34. int lca[MAX_N][MAX_D];
  35. int depth[MAX_N];
  36.  
  37. int getLCA(int a, int b) {
  38.   if(depth[a] < depth[b]) swap(a, b);
  39.   for(int d = MAX_D-1; d >= 0; d--) {
  40.     if(depth[a] - (1<<d) >= depth[b]) {
  41.       a = lca[a][d];
  42.     }
  43.   }
  44.   for(int d = MAX_D-1; d >= 0; d--) {
  45.     if(lca[a][d] != lca[b][d]) {
  46.       a = lca[a][d];
  47.       b = lca[b][d];
  48.     }
  49.   }
  50.   if(a != b) {
  51.     a = lca[a][0];
  52.     b = lca[b][0];
  53.   }
  54.   return a;
  55. }
  56.  
  57. void initLCA() {
  58.   for(int d = 1; d < MAX_D; d++) {
  59.     for(int i = 0; i < MAX_N; i++) {
  60.       lca[i][d] = lca[lca[i][d-1]][d-1];
  61.     }
  62.   }
  63. }
  64.  
  65. vector<int> edges[MAX_N];
  66. int treesz[MAX_N];
  67. int vertextosegtree[MAX_N];
  68. int topchain[MAX_N];
  69. int vals[MAX_N];
  70.  
  71. void dfsForHLD(int curr, int topPtr, int par, int& internalsegtreeidx) {
  72.   vertextosegtree[curr] = internalsegtreeidx++;
  73.   segtreeupd(vertextosegtree[curr], vals[curr]);
  74.   topchain[curr] = topPtr;
  75.   int largestchild = -1;
  76.   int largestsz = -1;
  77.   for(int out: edges[curr]) {
  78.     if(out == par) continue;
  79.     if(treesz[out] > largestsz) {
  80.       largestsz = treesz[out];
  81.       largestchild = out;
  82.     }
  83.   }
  84.   if(largestchild < 0) return;
  85.   dfsForHLD(largestchild, topPtr, curr, internalsegtreeidx);
  86.   for(int out: edges[curr]) {
  87.     if(out == par || out == largestchild) continue;
  88.     dfsForHLD(out, out, curr, internalsegtreeidx);
  89.   }
  90. }
  91.  
  92. void dfsForSize(int curr, int par) {
  93.   treesz[curr]++;
  94.   for(int out: edges[curr]) {
  95.     if(out == par) continue;
  96.     depth[out] = depth[curr] + 1;
  97.     lca[out][0] = curr;
  98.     dfsForSize(out, curr);
  99.     treesz[curr] += treesz[out];
  100.   }
  101. }
  102.  
  103. void initHLD() {
  104.   dfsForSize(0, -1);
  105.   initLCA();
  106.   int internalsegtreeidx = 0;
  107.   dfsForHLD(0, 0, -1, internalsegtreeidx);
  108. }
  109.  
  110. int pathQuery(int child, int par) {
  111.   int ret = 0;
  112.   while(child != par) {
  113.     if(topchain[child] == child) {
  114.       // light edge
  115.       ret ^= vals[child];
  116.       child = lca[child][0];
  117.     }
  118.     else if(depth[topchain[child]] > depth[par]) {
  119.       ret ^= segtreeqry(vertextosegtree[topchain[child]], vertextosegtree[child]);
  120.       child = lca[topchain[child]][0];
  121.     }
  122.     else {
  123.       ret ^= segtreeqry(vertextosegtree[par]+1, vertextosegtree[child]);
  124.       break;
  125.     }
  126.   }
  127.   return ret;
  128. }
  129.  
  130. int query(int a, int b) {
  131.   int r = getLCA(a, b);
  132.   return pathQuery(a, r) ^ pathQuery(b, r) ^ vals[r];
  133. }
  134.  
  135. int main() {
  136.   freopen("cowland.in", "r", stdin);
  137.   freopen("cowland.out", "w", stdout);
  138.   int n, q;
  139.   cin >> n >> q;
  140.   for(int i = 0; i < n; i++) {
  141.     cin >> vals[i];
  142.   }
  143.   for(int i = 1; i < n; i++) {
  144.     int a, b;
  145.     cin >> a >> b;
  146.     a--; b--;
  147.     edges[a].push_back(b);
  148.     edges[b].push_back(a);
  149.   }
  150.   initHLD();
  151.   while(q--) {
  152.     int t;
  153.     cin >> t;
  154.     if(t == 1) {
  155.       int i, v;
  156.       cin >> i >> v;
  157.       vals[--i] = v;
  158.       segtreeupd(vertextosegtree[i], v);
  159.     }
  160.     else {
  161.       int a, b;
  162.       cin >> a >> b;
  163.       cout << query(--a, --b) << "\n";
  164.     }
  165.   }
  166. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement