Advertisement
Guest User

Heavy light funfando

a guest
Mar 31st, 2015
253
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.67 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <iostream>
  4. #include <vector>
  5. #include <algorithm>
  6. #include <stack>
  7. #include <queue>
  8. #include <math.h>
  9. #include <string.h>
  10. #include <set>
  11. #include <map>
  12. #include <iostream>
  13. #include <sstream>
  14. #define MAXN 100001
  15. #define ll long long
  16.  
  17. using namespace std;
  18. using namespace std;
  19.  
  20. vector<vector<pair<int,int> > > g(MAXN);
  21.  
  22. int cnt[MAXN], prev[MAXN], chainNode[MAXN], chainHead[MAXN], posInChain[MAXN], base[MAXN], chainIdx = 0, idxSegTree = 0;
  23.  
  24. struct LCA{
  25.  
  26.     int H[MAXN], L[MAXN << 1], E[MAXN << 1], vis[MAXN], tree[MAXN * 8], idx;
  27.  
  28.     LCA(int root, int n){
  29.         idx = 0;
  30.         memset(H,-1,sizeof(H));
  31.         memset(L,0,sizeof(L));
  32.         memset(E,0,sizeof(E));
  33.         memset(vis,0,sizeof(vis));
  34.         dfs(root,0);
  35.         build(1, 0, 2*n-1);
  36.     }
  37.  
  38.     void dfs(int x, int depth){
  39.         vis[x] = 1;//visited
  40.         if(H[x] == -1) H[x] = idx;//mark first time the i'th node is visited
  41.         L[idx] = depth;//when you visit a node you should mark the the depth you have found it.
  42.         E[idx++] = x;//the i'th recursion, global variable
  43.         for(int i = 0; i < g[x].size(); i++){
  44.             int next = g[x][i].first;
  45.             if(!vis[next]){
  46.                 dfs(next, depth+1);
  47.                 L[idx] = depth;
  48.                 E[idx++] = x;
  49.             }
  50.         }
  51.     }
  52.  
  53.     //NlogN build the segtree and minimize the height of the I'th visited node
  54.     void build(int node, int l, int r){
  55.         if(l > r) return;
  56.         if(l == r){
  57.             tree[node] = l;
  58.         }else{
  59.             int mid = (l+r) >> 1;
  60.             build(node*2, l, mid);
  61.             build(node*2+1, mid+1, r);
  62.             int A = tree[node*2];
  63.             int B = tree[node*2+1];
  64.             if(L[A] <= L[B]){
  65.                 tree[node] = A;
  66.             }else{
  67.                 tree[node] = B;
  68.             }
  69.         }
  70.     }
  71.  
  72.     //Get the vertex with the minimum height, then it will be the LCA of A and B.
  73.     int rmq(int node, int l, int r, int ra, int rb){
  74.         if(l > rb || r < ra){
  75.             return -1;
  76.         }else if(l >= ra && r <= rb){
  77.             return tree[node];
  78.         }else{
  79.             int mid = (l+r) >> 1;
  80.             int q1 = rmq(node*2, l, mid, ra, rb);
  81.             int q2 = rmq(node*2+1, mid+1, r, ra, rb);
  82.             if(q1 == -1){
  83.                 return q2;
  84.             }else if(q2 == -1){
  85.                 return q1;
  86.             }else{
  87.                 if(L[q1] <= L[q2]){
  88.                     return q1;
  89.                 }else{
  90.                     return q2;
  91.                 }
  92.             }
  93.         }
  94.     }
  95.  
  96.     int getLCA(int u, int v, int n){
  97.         int goFrom = H[u];
  98.         int goTo = H[v];
  99.         if(goFrom > goTo){
  100.             swap(goFrom, goTo);
  101.         }
  102.         return E[rmq(1, 0, 2*n-1, goFrom, goTo)]; //is the LCA of A and B;
  103.      }
  104. };
  105.  
  106. struct SegTree{
  107.  
  108.     int tree[MAXN*4];
  109.  
  110.     void build(int node, int l, int r){
  111.         if(l > r) return;
  112.         if(l == r){
  113.             tree[node] = l;
  114.         }else{
  115.             int mid = (l+r) >> 1;
  116.             build(node*2, l, mid);
  117.             build(node*2+1, mid+1, r);
  118.             int A = tree[node*2];
  119.             int B = tree[node*2+1];
  120.             tree[node] = base[A] > base[B] ? A : B;
  121.         }
  122.     }
  123.  
  124.     int rmq(int node, int l, int r, int ra, int rb){
  125.         if(l > rb || r < ra){
  126.             return -1;
  127.         }else if(l >= ra && r <= rb){
  128.             return tree[node];
  129.         }else{
  130.             int mid = (l+r) >> 1;
  131.             int q1 = rmq(node*2, l, mid, ra, rb);
  132.             int q2 = rmq(node*2+1, mid+1, r, ra, rb);
  133.             if(q1 == -1){
  134.                 return q2;
  135.             }else if(q2 == -1){
  136.                 return q1;
  137.             }else{
  138.                 return base[q1] > base[q2] ? q1 : q2;
  139.             }
  140.         }
  141.     }
  142.    
  143.     void update(int node, int l, int r, int pos, int val){
  144.         if(l > r) return;
  145.         if(l == r && pos == r){
  146.             tree[node] = val;
  147.         }
  148.         int mid = (l+r)/2;
  149.         if(mid > pos){
  150.             update(node*2, l, mid, pos, val);
  151.         }else if(mid > pos){
  152.             update(node*2+1, mid+1, r, pos, val);
  153.         }
  154.         tree[node] = max(tree[node*2], tree[node*2+1]);
  155.     }
  156. };
  157.  
  158. //Decompose the tree into chains
  159. void HLD(int node, int cost, int parent){
  160.     if(chainHead[chainIdx] == -1){
  161.         chainHead[chainIdx] = node;
  162.     }
  163.     chainNode[node] = chainIdx;
  164.     posInChain[node] = idxSegTree;
  165.     base[idxSegTree++] = cost;
  166.     int nodeHeavy = -1, nextCost;
  167.     //seeking the special child (the one with most childs on the subtrees)
  168.     for(int i = 0; i < g[node].size(); i++){
  169.         int next = g[node][i].first;
  170.         if(next != parent && (nodeHeavy == -1 || cnt[next] > cnt[nodeHeavy])){
  171.             nodeHeavy = next;
  172.             nextCost = g[node][i].second;
  173.         }
  174.     }
  175.     if(nodeHeavy > -1){
  176.         //expanding the current chain
  177.         HLD(nodeHeavy, nextCost, node);
  178.     }
  179.    
  180.     for(int i = 0; i < g[node].size(); i++){
  181.         int next = g[node][i].first;
  182.         if(next != nodeHeavy && next != parent){
  183.             chainIdx++;
  184.             HLD(next, g[node][i].second, node);
  185.         }
  186.     }
  187.  
  188. }
  189.  
  190. void dfsCnt(int node, int parent){
  191.     cnt[node] = 1;
  192.     for(int i = 0; i < g[node].size(); i++){
  193.         int next = g[node][i].first;
  194.         if(next != parent){
  195.             prev[next] = node;
  196.             dfsCnt(next, node);
  197.             cnt[node] += cnt[next];
  198.         }
  199.     }  
  200. }
  201.  
  202. int walkChain(int U, int V, SegTree &q, int n){
  203.     if(U == V) return 0;
  204.     int ans = 0;
  205.     while(chainNode[U] != chainNode[V]){
  206.         int Left = posInChain[chainHead[chainNode[U]]];
  207.         int Right = posInChain[U];
  208.         int val = base[q.rmq(1, 0, n-1, Left, Right)];
  209.         if(val > ans) ans = val;
  210.         U = prev[chainHead[chainNode[U]]];
  211.     }
  212.     if(U == V) return ans;
  213.     int val = base[q.rmq(1, 0, n-1, posInChain[V]+1, posInChain[U])];
  214.     if(val > ans) ans = val;
  215.     return ans;
  216. }
  217.  
  218. int getMax(int U, int V, LCA &ref, SegTree &q, int n){
  219.     int lca = ref.getLCA(U, V, n),a=0,b=0;
  220.     if(lca != U)
  221.         a = walkChain(U, lca, q, n);
  222.     if(lca != V)
  223.         b = walkChain(V, lca, q, n);
  224.     return max(a,b);
  225. }
  226.  
  227. void add(int a, int b, int c){
  228.     g[a].push_back(make_pair(b,c));
  229.     g[b].push_back(make_pair(a,c));
  230. }
  231.  
  232. int main(void){
  233.     int n = 14;
  234.     add(0, 1, 1);
  235.     add(0, 4, 3);
  236.     add(0, 5, 1);
  237.     add(1, 2, 2);
  238.     add(1, 3, 2);
  239.     add(4, 13, 11);
  240.     add(5, 6, 3);
  241.     add(5, 7, 6);
  242.     add(5, 8, 2);
  243.     add(7, 9, 1);
  244.     add(7, 10, 4);
  245.     add(10, 11, 2);
  246.     add(10, 12, 3);
  247.     memset(chainHead,-1,sizeof(chainHead));
  248.     dfsCnt(0,-1);
  249.     HLD(0,-1, -1);
  250.     LCA lca(0,n);
  251.     SegTree query;
  252.     query.build(1,0,n-1);
  253.     for(int i = 0; i < idxSegTree; i++) cout << base[i] << " ";
  254.     return 0;
  255. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement