Matrix_code

data-structure - Heavy - light (1348 - Aladdin and the Return Journey)

Apr 23rd, 2016 (edited)
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.20 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. /*------- Constants---- */
  4.  
  5. #define Long                    long long
  6. #define Ulong                   unsigned long long
  7. #define forn(i,n)               for( int i=0 ; i < n ; i++ )
  8. #define mp(i,j)                 make_pair(i,j)
  9. #define pb(a)                   push_back((a))
  10. #define all(x)                  (x).begin(),(x).end()
  11. #define gc                      getchar_unlocked
  12. #define PI                      acos(-1.0)
  13. #define EPS                     1e-9
  14. #define xx                      first
  15. #define yy                      second
  16. #define lc                      ((n)<<1)
  17. #define rc                      ((n)<<1|1)
  18. #define db(x)                   cout << #x << " -> " << x << endl;
  19. #define Di(x)                   int x;scanf("%d",&x)
  20. #define min(a,b)                ((a)>(b) ? (b) : (a) )
  21. #define max(a,b)                ((a)>(b) ? (a):(b))
  22. #define ms(ara_name,value)      memset(ara_name,value,sizeof(ara_name))
  23.  
  24. /*************************** END OF TEMPLATE ****************************/
  25.  
  26. const int N = 3e4+4 , LG = 20;
  27. int n;
  28. int P[N][20], lev[N], ch = 0;
  29. int chainNo[N], head[N], subsize[N], child[N], pos[N];
  30. int Ar[N], tot = 0 , value[N];
  31.  
  32. vector<int> G[N];
  33.  
  34.  
  35.  
  36. int seg[N*4];
  37. void build(int n,int b,int e)
  38. {
  39.     if(b==e) {
  40.         seg[n] = Ar[b];return;
  41.     }
  42.     int mid= (b+e)/2;
  43.     build(lc,b,mid);
  44.     build(rc, mid+1,e);
  45.     seg[n] = seg[lc] + seg[rc];
  46. }
  47. void update(int n,int b,int e,int pos,int v)
  48. {
  49.     if(b==e && b== pos) {
  50.         seg[n] = v;
  51.         return ;
  52.     }
  53.     int mid = (b+e)/2;
  54.     if(pos <= mid ) update(lc,b,mid,pos,v);
  55.     else update(rc,mid+1,e,pos,v);
  56.     seg[n] = seg[lc] + seg[rc];
  57. }
  58.  
  59. int query(int n,int b,int e,int i,int j)
  60. {
  61.     if(b>j||e<i) return 0;
  62.     if(b>=i && e <= j ) {
  63.         return seg[n];
  64.     }
  65.     int mid = (b+e)/2;
  66.     return query(lc,b,mid,i,j) + query(rc,mid+1,e,i,j);
  67. }
  68. /********** MAIN HLD-PART **********************/
  69. void dfs(int u,int p)
  70. {
  71.     subsize[u] = 1;
  72.     for(int i = 0; i < G[u].size(); i ++ ) {
  73.         int v = G[u][i];
  74.         if(v == p ) continue;
  75.         lev[v] = 1  + lev[u];
  76.         P[v][0] = u; // Modify
  77.         dfs(v,u);
  78.  
  79.         subsize[u] += subsize[v];
  80.         if(child[u] == -1 || subsize[v] > subsize[child[u]] ) {
  81.             child[u] = v;
  82.         }
  83.  
  84.     }
  85. }
  86. void HLD(int u,int p)
  87. {
  88.     if(head[ch] == -1) head[ch] = u;
  89.     Ar[ ++tot ] = value[u];
  90.     pos[u] = tot;
  91.     chainNo[u] = ch;
  92.  
  93.     if(child[u]  > 0 ) HLD(child[u], u );
  94.     for(int i = 0; i < G[u].size(); i ++ ) {
  95.         int v = G[u][i];
  96.         if(v == p || v == child[u]) continue;
  97.         ++ch;
  98.         HLD(v,u);
  99.     }
  100. }
  101.  
  102. int LCA(int u,int v)
  103. {
  104.     if(lev[u] > lev[v]) swap(u,v);
  105.     int d = lev[v] - lev[u];
  106.     for(int i = LG - 1; i >= 0 ;  i -- ) {
  107.         if( d  &1<<i){
  108.             v = P[v][i];
  109.         }
  110.     }
  111.    
  112.     if(u==v) return u;
  113.     for(int i = LG-1; i >= 0 ; i -- ) {
  114.         if(P[u][i] != P[v][i]) {
  115.             u = P[u][i];
  116.             v = P[v][i];
  117.         }
  118.     }
  119.     return P[v][0];
  120. }
  121.  
  122. int queryUp(int from, int to) // Climb up to
  123. {
  124.     int ret = 0;
  125.     while(chainNo[from ] != chainNo[to] ) {
  126.         int h = head[chainNo[from]];
  127.         ret += query(1,1,tot, pos[h], pos[from]); // Modify
  128.         from = P[h][0];
  129.     }
  130.     ret += query(1,1,tot,pos[to], pos[from]); // Modify
  131.     return ret;
  132. }
  133. void process()
  134. {
  135.     memset(P,-1,sizeof(P));
  136.     memset(head,-1,sizeof(head));
  137.     memset(child,-1,sizeof(child));
  138.    
  139.     tot = 0 , ch = 0;
  140.     dfs(1,-1);
  141.     HLD(1,-1);
  142.     build(1,1,tot);
  143.     for(int i = 1; i < LG; i ++ ) {
  144.         for(int j = 1; j <= n; j ++ ) if(P[j][i-1] !=-1 ) P[j][i] = P[P[j][i-1]][i-1];
  145.     }
  146. }
  147. /************************** END ************************/
  148. int main()
  149. {
  150.     //freopen("in.txt","r",stdin);
  151.     int t,cs=  0;
  152.     scanf("%d",&t);
  153.     while(t--) {
  154.         scanf("%d",&n);
  155.  
  156.         for(int i= 1;i <= n; i ++) scanf("%d",&value[i]);
  157.         for(int i = 1; i <= n-1; i ++ ) {
  158.             int a,b;
  159.             scanf("%d %d",&a,&b);
  160.             a++,b++;
  161.             G[a].pb(b);
  162.             G[b].pb(a);
  163.         }
  164.         process();
  165.         int q;
  166.         scanf("%d",&q);
  167.         printf("Case %d:\n", ++cs);
  168.         while(q--){
  169.             int type;
  170.             scanf("%d",&type);
  171.             if(type == 0) {
  172.                 int a,b;
  173.                 scanf("%d %d",&a,&b);
  174.                 a++,b++;
  175.                 int k = LCA(a,b);
  176.                 printf("%d\n", queryUp(a,k) + queryUp(b,k) - value[k]); // Climbing Up
  177.             }
  178.             else {
  179.                 int a,b;
  180.                 scanf("%d %d",&a,&b); a ++;
  181.                 value[a]  = b;
  182.                 update(1,1,tot,pos[a],b);
  183.             }
  184.         }
  185.         for(int i = 1;i <= n; i ++ ) G[i].clear();
  186.     }
  187.     return 0;
  188. }
Add Comment
Please, Sign In to add comment