Advertisement
Jasir

HLD

Aug 13th, 2018
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.89 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define mx 20005
  6. #define inf 1000000000000000000
  7. #define int long long
  8. #define piii pair <int, pair <int, int> >
  9. #define pii pair <int, int>
  10. #define f first
  11. #define s second
  12. #define mp make_pair
  13. #define lc  ((n)<<1)
  14. #define rc  ((n)<<1|1)
  15.  
  16. const int N = 3e4+4 , LG = 20;
  17. int n;
  18. int P[N][20], lev[N], ch = 0;
  19. int chainNo[N], head[N], subsize[N], child[N], pos[N];
  20. int Ar[N], tot = 0 , value[N];
  21.  
  22. vector<int> G[N];
  23.  
  24. int seg[N*4];
  25. void build(int n,int b,int e){
  26.     if(b==e) {
  27.         seg[n] = Ar[b];return;
  28.     }
  29.     int mid= (b+e)/2;
  30.     build(lc,b,mid);
  31.     build(rc, mid+1,e);
  32.     seg[n] = seg[lc] + seg[rc];
  33. }
  34.  
  35. void update(int n,int b,int e,int pos,int v){
  36.     if(b==e && b== pos) {
  37.         seg[n] = v;
  38.         return ;
  39.     }
  40.     int mid = (b+e)/2;
  41.     if(pos <= mid ) update(lc,b,mid,pos,v);
  42.     else update(rc,mid+1,e,pos,v);
  43.     seg[n] = seg[lc] + seg[rc];
  44. }
  45.  
  46. int query(int n,int b,int e,int i,int j){
  47.     if(b>j||e<i) return 0;
  48.     if(b>=i && e <= j ) {
  49.         return seg[n];
  50.     }
  51.     int mid = (b+e)/2;
  52.     return query(lc,b,mid,i,j) + query(rc,mid+1,e,i,j);
  53. }
  54.  
  55. void dfs(int u,int p){
  56.     subsize[u] = 1;
  57.     for(int i = 0; i < G[u].size(); i ++ ) {
  58.         int v = G[u][i];
  59.         if(v == p ) continue;
  60.         lev[v] = 1  + lev[u];
  61.         P[v][0] = u; // Modify
  62.         dfs(v,u);
  63.         subsize[u] += subsize[v];
  64.         if(child[u] == -1 || subsize[v] > subsize[child[u]] ) {
  65.             child[u] = v;
  66.         }
  67.  
  68.     }
  69. }
  70.  
  71. void HLD(int u,int p){
  72.     if(head[ch] == -1) head[ch] = u;
  73.     Ar[ ++tot ] = value[u];
  74.     pos[u] = tot;
  75.     chainNo[u] = ch;
  76.  
  77.     if(child[u]  > 0 ) HLD(child[u], u );
  78.     for(int i = 0; i < G[u].size(); i ++ ) {
  79.         int v = G[u][i];
  80.         if(v == p || v == child[u]) continue;
  81.         ++ch;
  82.         HLD(v,u);
  83.     }
  84. }
  85.  
  86. int LCA(int u,int v){
  87.     if(lev[u] > lev[v]) swap(u,v);
  88.     int d = lev[v] - lev[u];
  89.     for(int i = LG - 1; i >= 0 ;  i -- ) {
  90.         if( d  &1<<i){
  91.             v = P[v][i];
  92.         }
  93.     }
  94.  
  95.     if(u==v) return u;
  96.     for(int i = LG-1; i >= 0 ; i -- ) {
  97.         if(P[u][i] != P[v][i]) {
  98.             u = P[u][i];
  99.             v = P[v][i];
  100.         }
  101.     }
  102.     return P[v][0];
  103. }
  104.  
  105. int queryUp(int from, int to){ // Climb up to
  106.     int ret = 0;
  107.     while(chainNo[from ] != chainNo[to] ) {
  108.         int h = head[chainNo[from]];
  109.         ret += query(1,1,tot, pos[h], pos[from]); // Modify
  110.         from = P[h][0];
  111.     }
  112.     ret += query(1,1,tot,pos[to], pos[from]); // Modify
  113.     return ret;
  114. }
  115.  
  116. void process(){
  117.     memset(P,-1,sizeof(P));
  118.     memset(head,-1,sizeof(head));
  119.     memset(child,-1,sizeof(child));
  120.  
  121.     tot = 0 , ch = 0;
  122.     dfs(1,-1);
  123.     HLD(1,-1);
  124.     build(1,1,tot);
  125.     for(int i = 1; i < LG; i ++ ) {
  126.         for(int j = 1; j <= n; j ++ ) if(P[j][i-1] !=-1 ) P[j][i] = P[P[j][i-1]][i-1];
  127.     }
  128. }
  129.  
  130. int32_t main(){
  131.     //freopen("in.txt", "r", stdin);
  132.     int m, k, p, cas, d, t;
  133.     scanf("%lld", &t);
  134.     cas = 1;
  135.     while(t--){
  136.         scanf("%lld", &n);
  137.         for(int i=1;i<=n;i++){
  138.             scanf("%lld", &value[i]);
  139.         }
  140.         for(int i=1;i<=n-1;i++){
  141.             int a, b;
  142.             scanf("%lld%lld", &a, &b);
  143.             a++;
  144.             b++;
  145.             G[a].push_back(b);
  146.             G[b].push_back(a);
  147.         }
  148.         scanf("%lld", &p);
  149.         process();
  150.         printf("Case %lld:\n", cas++);
  151.         while(p--){
  152.             int a, b;
  153.             scanf("%lld%lld%lld", &m, &a, &b);
  154.             a++;
  155.             if(m){
  156.                 value[a] = b;
  157.                 update(1, 1, n, pos[a], b);
  158.             }
  159.             else{
  160.                 b++;
  161.                 k = LCA(a, b);
  162.                 printf("%lld\n", queryUp(a, k)+queryUp(b, k)-value[k]);
  163.             }
  164.         }
  165.         for(int i=0;i<=n;i++) G[i].clear();
  166.  
  167.     }
  168.     return 0;
  169. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement