Advertisement
Tarango

Aladdin and the Return Journey

Sep 22nd, 2015
547
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.31 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define Size 100005
  4.  
  5. #define root 1
  6. #define N 30100
  7. #define LN 14
  8.  
  9. vector<int> Graph[N];
  10. int treeArray[N], Node;
  11. int chainNo, chainInd[N], chainHead[N], posInTree[N];
  12. int depth[N], sparseTable[N][LN], subSize[N];
  13. long long tree[N * 6];
  14. long long Cost[N];
  15. int n;
  16.  
  17. void build_tree(int cur, int Start, int End) {
  18.     if (Start == End) {
  19.         tree[cur] = treeArray[Start];
  20.         return;
  21.     }
  22.     int left = cur*2;
  23.     int right = left+1;
  24.     int mid = (Start+End)/2;
  25.     build_tree(left,Start,mid);
  26.     build_tree(right,mid+1,End);
  27.     tree[cur] = tree[left]+tree[right];
  28. }
  29.  
  30. void update_tree(int cur, int Start, int End, int u, int v, long long value) {
  31.     if (Start > v || End < u)
  32.         return;
  33.     if (Start >= u && End <= v) {
  34.         tree[cur] = value;
  35.         return;
  36.     }
  37.     int left = cur*2;
  38.     int right = left+1;
  39.     int mid = (Start+End)/2;
  40.  
  41.     update_tree(left,Start,mid,u,v,value);
  42.     update_tree(right,mid+1,End,u,v,value);
  43.     tree[cur] = tree[left]+tree[right];
  44. }
  45.  
  46. long long query_Tree(int cur, int Start, int End, int u, int v) {
  47.     if (Start > v || End < u) {
  48.         return 0;
  49.     }
  50.     if (Start >= u && End <= v) {
  51.         return tree[cur];
  52.     }
  53.     int left = cur*2;
  54.     int right = left+1;
  55.     int mid = (Start+End)/2;
  56.  
  57.     long long v1 = query_Tree(left,Start,mid,u,v);
  58.     long long v2 = query_Tree(right,mid+1,End,u,v);
  59.     long long sum = v1+v2;
  60.     //printf("Cur sum: %lld\n",sum);
  61.     return sum;
  62. }
  63.  
  64. long long query_up(int u, int v) {
  65.     if (u == v) {
  66.         //return 0;
  67.         return query_Tree(1, 1, Node, posInTree[u], posInTree[u]);
  68.     }
  69.     int uchain, vchain = chainInd[v];
  70.     long long ans = 0;
  71.     while (true) {
  72.         uchain = chainInd[u];
  73.         if (uchain == vchain) {
  74.             int st = posInTree[v];
  75.             int ed = posInTree[u];
  76.             long long ret = query_Tree(1, 1, Node, st, ed);
  77.             //printf("st: %d , ed: %d = %lld\n",st,ed,ret);
  78.             ans += ret;
  79.             break;
  80.         }
  81.         int st = posInTree[chainHead[uchain]];
  82.         int ed = posInTree[u];
  83.         long long ret = query_Tree(1, 1, Node, st, ed);
  84.         //printf("st: %d , ed: %d = %lld\n",st,ed,ret);
  85.         ans += ret;
  86.         u = chainHead[uchain];
  87.         u = sparseTable[u][0];
  88.         //cout << ans << endl;
  89.     }
  90.     return ans;
  91. }
  92.  
  93. int LCA(int u, int v) {
  94.     if (depth[u] < depth[v]){
  95.         swap(u, v);
  96.     }
  97.     int diff = depth[u] - depth[v];
  98.     for (int i = 0; i < LN; i++) {
  99.         if ((diff >> i) & 1) {
  100.             u = sparseTable[u][i];
  101.         }
  102.     }
  103.     if (u == v){
  104.         return u;
  105.     }
  106.     for (int i = LN - 1; i >= 0; i--) {
  107.         if (sparseTable[u][i] != sparseTable[v][i]) {
  108.             u = sparseTable[u][i];
  109.             v = sparseTable[v][i];
  110.         }
  111.     }
  112.     return sparseTable[u][0];
  113. }
  114.  
  115. void build_Sparse_Table() {
  116.     for (int i = 1; i < LN; i++) {
  117.         for (int j = 1; j <= N; j++) {
  118.             if (sparseTable[j][i - 1] != -1) {
  119.                 sparseTable[j][i] = sparseTable[sparseTable[j][i - 1]][i - 1];
  120.             }
  121.         }
  122.     }
  123. }
  124.  
  125. long long query(int u, int v) {
  126.     //return query_up(11,1);
  127.     int lca = LCA(u, v);
  128.     long long ret1 = query_up(u, lca);
  129.     long long ret2 = query_up(v, lca);
  130.     long long merge = query_up(lca, lca);
  131.     //printf("LCA: %d , ret1: %lld , ret2: %lld\n",lca,ret1,ret2);
  132.     return (ret1+ret2-merge);
  133. }
  134.  
  135. void updateNode(int u, long long val) {
  136.     update_tree(1, 1, Node, posInTree[u],posInTree[u], val);
  137. }
  138.  
  139. void HLD(int curNode,int prev) {
  140.     if (chainHead[chainNo] == -1) {
  141.         chainHead[chainNo] = curNode;
  142.     }
  143.     chainInd[curNode] = chainNo;
  144.     posInTree[curNode] = Node;
  145.     treeArray[Node++] = Cost[curNode];
  146.  
  147.     int newNode = -1;
  148.     for (int i = 0; i < (int) Graph[curNode].size(); i++) {
  149.         if (Graph[curNode][i] != prev) {
  150.             if (newNode == -1 || subSize[newNode] < subSize[Graph[curNode][i]]) {
  151.                 newNode = Graph[curNode][i];
  152.             }
  153.         }
  154.     }
  155.  
  156.     if (newNode != -1) {
  157.         HLD(newNode, curNode);
  158.     }
  159.  
  160.     for (int i = 0; i < (int) Graph[curNode].size(); i++) {
  161.         if (Graph[curNode][i] != prev) {
  162.             if (newNode != Graph[curNode][i]) {
  163.                 chainNo++;
  164.                 HLD(Graph[curNode][i], curNode);
  165.             }
  166.         }
  167.     }
  168. }
  169.  
  170. void DFS(int cur, int prev, int level = 0) {
  171.     sparseTable[cur][0] = prev;
  172.     depth[cur] = level;
  173.     subSize[cur] = 1;
  174.     for (int i = 0; i < (int) Graph[cur].size(); i++)
  175.         if (Graph[cur][i] != prev) {
  176.             DFS(Graph[cur][i], cur, level + 1);
  177.             subSize[cur] += subSize[Graph[cur][i]];
  178.         }
  179. }
  180.  
  181. void printTree(){
  182.     for(int i = 1;i<=n;i++){
  183.         printf("cur: %d\n",i);
  184.         printf("   chain Ind: %d , tree Pos: %d\n",chainInd[i],posInTree[i]);
  185.         printf("   depth: %d , tree Array: %d\n",depth[i],treeArray[i]);
  186.         printf("   belongs to %d subSize: %d\n",chainHead[chainInd[i]],subSize[i]);
  187.     }
  188. }
  189.  
  190. int main() {
  191.     int nCase,Q,typ,u,v;
  192.     long long val;
  193.     scanf("%d ", &nCase);
  194.     for (int cs = 1; cs <= nCase; cs++) {
  195.         scanf("%d", &n);
  196.         chainHead[0] = -1;
  197.         for (int i = 1; i <= n; i++) {
  198.             scanf("%lld",&Cost[i]);
  199.             Graph[i].clear();
  200.             chainHead[i] = -1;
  201.             for (int j = 0; j < LN; j++) {
  202.                 sparseTable[i][j] = -1;
  203.             }
  204.         }
  205.         for (int i = 0; i < n - 1; i++) {
  206.             scanf("%d %d", &u, &v);
  207.             u++,v++;
  208.             Graph[u].push_back(v);
  209.             Graph[v].push_back(u);
  210.         }
  211.         Node = 1;
  212.         chainNo = 0;
  213.         DFS(root, -1);
  214.         HLD(root, -1);
  215.         Node--;
  216.         //printTree();
  217.         build_tree(1, 1, Node);
  218.         build_Sparse_Table();
  219.         printf("Case %d:\n",cs);
  220.         scanf("%d",&Q);
  221.  
  222.         for(int i = 0;i<Q;i++){
  223.             scanf("%d",&typ);
  224.             if (typ == 0) {
  225.                 scanf("%d %d",&u,&v);
  226.                 u++,v++;
  227.                 long long ans = query(u,v);
  228.                 printf("%lld\n", ans);
  229.             } else {
  230.                 scanf("%d %lld",&u,&val);
  231.                 u++;
  232.                 updateNode(u, val);
  233.             }
  234.         }
  235.     }
  236. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement