Advertisement
RaFiN_

HLD

Feb 28th, 2019
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.65 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define pii pair<int,int>
  5. #define ff first
  6. #define ss second
  7. #define mx 40100
  8. int base[mx],tree[6*mx],level[mx],parent[mx],SubtrSiz[mx],arr[mx];vector<int>adj[mx];
  9.  
  10. int chainLeader[mx],chain[mx],basepos[mx],ptr=1,ch;
  11.  
  12.  
  13. void Build(int node,int b,int e)
  14. {
  15.     if(b==e)
  16.     {
  17.         tree[node]=base[b];
  18.         return;
  19.     }
  20.     int mid=(b+e)/2;
  21.     int left=2*node;
  22.     int right=left+1;
  23.     Build(left,b,mid);
  24.     Build(right,mid+1,e);
  25.     tree[node]=tree[left]+tree[right];
  26. }
  27.  
  28. int query(int node,int b,int e,int l,int r)
  29. {
  30.     if(b>r||l>e)return 0;
  31.  
  32.     if(b>=l&&e<=r)return tree[node];
  33.  
  34.     int mid=(b+e)/2;
  35.     int left=2*node;
  36.     int right=left+1;
  37.  
  38.     int p1=query(left,b,mid,l,r);
  39.     int p2=query(right,mid+1,e,l,r);
  40.  
  41.     return p1+p2;
  42. }
  43.  
  44. void update(int node,int b,int e,int newVal,int pos)
  45. {
  46.     if(b>pos||e<pos)return;
  47.     if(b==e)
  48.     {
  49.         base[b]=newVal;
  50.         tree[node]=base[b];
  51.         return;
  52.     }
  53.     int mid=(b+e)/2;
  54.     int left=2*node;
  55.     int right=left+1;
  56.     update(left,b,mid,newVal,pos);
  57.     update(right,mid+1,e,newVal,pos);
  58.     tree[node]=tree[left]+tree[right];
  59. }
  60.  
  61. int dfs(int s,int lev,int pr)
  62. {
  63.     level[s]=lev;
  64.     parent[s]=pr;
  65.     SubtrSiz[s]=1;
  66.     for(int i=0;i<adj[s].size();i++)
  67.     {
  68.         int u=adj[s][i];
  69.         if(u!=parent[s])
  70.         {
  71.             SubtrSiz[s]+=dfs(u,lev+1,s);
  72.         }
  73.     }
  74.     return SubtrSiz[s];
  75. }
  76.  
  77.  
  78. void HLD(int node,int chainNo,int cst,bool isL)
  79. {
  80.     if(isL)
  81.     {
  82.         chainNo=++ch;
  83.         chainLeader[chainNo]=node;
  84.     }
  85.  
  86.     chain[node]=chainNo;
  87.     basepos[node]=ptr;
  88.     base[ptr++]=cst;
  89.  
  90.     int Heavy=-1,Heavynode,Heavycost;
  91.     for(int i=0;i<adj[node].size();i++)
  92.     {
  93.         int u=adj[node][i];
  94.         if(u==parent[node])continue;
  95.         if(SubtrSiz[u]>Heavy)
  96.         {
  97.             Heavy=SubtrSiz[u];
  98.             Heavynode=u;
  99.             Heavycost=arr[u];
  100.         }
  101.     }
  102.  
  103.     if(Heavy==-1)return;
  104.     HLD(Heavynode,chainNo,Heavycost,false);
  105.  
  106.     for(int i=0;i<adj[node].size();i++)
  107.     {
  108.         int u=adj[node][i];
  109.         int w=arr[u];
  110.         if(u==parent[node]||u==Heavynode)continue;
  111.         HLD(u,0,w,true);
  112.     }
  113. }
  114.  
  115. int lca(int u,int v)
  116. {
  117.     while(chain[u]!=chain[v])
  118.     {
  119.         if(level[chainLeader[chain[u]]]>level[chainLeader[chain[v]]])
  120.         {
  121.             u=parent[chainLeader[chain[u]]];
  122.         }
  123.         else
  124.             v=parent[chainLeader[chain[v]]];
  125.     }
  126.  
  127.     if(level[u]<level[v])return u;
  128.     else return v;
  129. }
  130.  
  131.  
  132. int query_up(int u,int v)
  133. {
  134.     int maxi=0;
  135.     while(1)
  136.     {
  137.         //cout<<basepos[u]<<" "<<basepos[v]<<" "<<u<<" "<<v<<endl;
  138.         if(chain[u]==chain[v])
  139.         {
  140.             int x=query(1,1,ptr,min(basepos[u],basepos[v]),max(basepos[u],basepos[v]));
  141.             maxi+=x;
  142.             break;
  143.         }
  144.         int y=query(1,1,ptr,min(basepos[u],basepos[chainLeader[chain[u]]]),max(basepos[u],basepos[chainLeader[chain[u]]]));
  145.         maxi+=y;
  146.         u=parent[chainLeader[chain[u]]];
  147.     }
  148.  
  149.     return maxi;
  150. }
  151.  
  152. int giveres(int node1,int node2)
  153. {
  154.     int LCA=lca(node1,node2);
  155.     //cout<<LCA<<endl;
  156.     int max1=query_up(node1,LCA);
  157.     int max2=query_up(node2,LCA);
  158.     return max1+max2-base[basepos[LCA]];
  159. }
  160.  
  161. int main()
  162. {
  163.  
  164.     int t;
  165.     scanf("%d",&t);
  166.     for(int q=0;q<t;q++)
  167.     {
  168.         int n;
  169.         scanf("%d",&n);
  170.         for(int i=1;i<=n;i++)scanf("%d",&arr[i]);
  171.         int root=1;
  172.         for(int i=0;i<=n;i++)
  173.         {
  174.             adj[i].clear();
  175.         }
  176.         ptr=1;ch=0;
  177.         for(int i=0;i<n-1;i++)
  178.         {
  179.             int a,b,c;
  180.             scanf("%d%d",&a,&b);
  181.             a++;b++;
  182.             adj[a].push_back(b);
  183.             adj[b].push_back(a);
  184.             root=1;
  185.         }
  186.  
  187.         dfs(root,1,root);
  188.         HLD(root,0,arr[1],true);
  189.         ptr--;
  190.         Build(1,1,ptr);
  191.         int qt;
  192.         scanf("%d",&qt);
  193.         printf("Case %d:\n",q+1);
  194.         for(int i=0;i<qt;i++)
  195.         {
  196.             int cho;
  197.             scanf("%d",&cho);
  198.             if(cho==0)
  199.             {
  200.                 int node1,node2;
  201.                 scanf("%d%d",&node1,&node2);
  202.                 node1++;node2++;
  203.                // for(int i=1;i<=ptr;i++)cout<<base[i]<<" ";cout<<endl;
  204.                 //cout<<query(1,1,ptr,3,6)<<endl;
  205.                 printf("%d\n",giveres(node1,node2));
  206.             }
  207.             else
  208.             {
  209.                 int ed,val;
  210.                 scanf("%d%d",&ed,&val);
  211.                 ed++;
  212.                 arr[ed]=val;
  213.                 update(1,1,ptr,val,basepos[ed]);
  214.             }
  215.         }
  216.  
  217.     }
  218.  
  219.    
  220. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement