Advertisement
Rana_093

HLD

Oct 23rd, 2018
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.51 KB | None | 0 0
  1. ///http://lightoj.com/volume_showproblem.php?problem=1348
  2. #include<bits/stdc++.h>
  3.  
  4. using namespace std;
  5.  
  6. #define ll long long int
  7. #define db(x) cout<<#x<<" -> "<<x<<endl
  8. #define maxn 30005
  9. #define xx first
  10. #define yy second
  11. #define mp make_pair
  12.  
  13. typedef pair< int , int > pii;
  14.  
  15. int sub[maxn],d[maxn],par[maxn];
  16. bool vis[maxn];
  17. int P[maxn][17];
  18. vector< int > g[maxn];
  19. int st[maxn*6],qt[maxn*6];
  20. int chainHead[maxn];
  21. int chainInd[maxn],posInBase[maxn],baseArray[maxn];
  22. int Cost[maxn],otherEnd[maxn];
  23. int n,chainNo=0,ptr=0;
  24. int root ;
  25.  
  26. void clr(){
  27.     memset(vis,false,sizeof(vis));
  28.     memset(chainHead,-1,sizeof(chainHead));
  29.     chainNo = 0;
  30.     ptr  = 0;
  31.     root = 0;
  32.     for(int i=0; i<=n+5; i++){
  33.         g[i].clear();
  34.     }
  35. }
  36.  
  37. void dfs(int src, int parent, int dep){
  38.     par[src] =  parent;
  39.     vis[src] =  true;
  40.     d[src]   =  dep;
  41.     sub[src] =  1;
  42.     for(int i=0; i<g[src].size(); i++){
  43.         int temp = g[src][i];
  44.         if( vis[temp] )  continue;
  45. //        otherEnd[index[src][i]] = temp;
  46.         dfs(temp,src,dep+1);
  47.         sub[src]+=sub[temp];
  48.     }
  49. }
  50.  
  51. int lca_query(int p, int q){
  52.     if( d[p] < d[q] ) swap(p,q);
  53.     int log = 1;
  54.     while(true){
  55.         int next = log+1;
  56.         if((1<<next)>d[p]) break;
  57.         log++;
  58.     }
  59.     for(int i=log; i>=0; i--){
  60.         if((d[p]-(1<<i))>=d[q]){
  61.             p = P[p][i];
  62.         }
  63.     }
  64.     if(p==q) return p;
  65.     for(int i=log; i>=0; i--){
  66.         if(P[p][i]!=-1 && P[p][i]!=P[q][i]){
  67.             p = P[p][i] ; q = P[q][i];
  68.         }
  69.     }
  70.     return par[p];
  71. }
  72.  
  73. void lca_init(){
  74.     memset(P,-1,sizeof(P));
  75.     for(int i=0; i<n; i++){
  76.         P[i][0] = par[i];
  77.     }
  78.     for(int j=1; (1<<j)<n; j++){
  79.         for(int i=0; i<n; i++){
  80.             if( P[i][j-1]== -1 ) continue;
  81.             P[i][j] = P[P[i][j-1]][j-1];
  82.         }
  83.     }
  84. }
  85.  
  86. void HLD(int curNode, int cost , int prev){
  87.     if(chainHead[chainNo]==-1){
  88.         chainHead[chainNo] = curNode;
  89.     }
  90.     chainInd[curNode] = chainNo;
  91.     posInBase[curNode] = ptr;
  92.     baseArray[ptr++] = cost;
  93.     int sc = -1;
  94.     int ncost;
  95.     ///Loop to find special child
  96.     for(int i=0; i<g[curNode].size(); i++){
  97.         int temp = g[curNode][i];
  98.         if(temp == prev) continue;
  99.         if(sc==-1 || sub[sc]<sub[temp]){
  100.             sc = temp;
  101.             ncost = Cost[g[curNode][i]];
  102.         }
  103.     }
  104.     if(sc!=-1){
  105.         ///Expand the chain;
  106.         HLD(sc,ncost,curNode);
  107.     }
  108.     for(int i=0; i<g[curNode].size(); i++){
  109.         int temp = g[curNode][i];
  110.         if(temp == prev) continue;
  111.         if(sc!=temp){
  112.             ///New chain at each normal node;
  113.             chainNo++;
  114.             HLD(temp,Cost[temp],curNode);
  115.         }
  116.     }
  117. }
  118.  
  119. ///make segment tree it uses the baseArray for building segment tree
  120. void make_tree(int cur, int s, int e){
  121.     if(s==e-1){
  122.         st[cur] = baseArray[s];
  123.         return ;
  124.     }
  125.     int c1 = (cur<<1) , c2 = c1|1 , m = (s+e)>>1;
  126.     /// in [s,e) range so (s,m) & (m,e) in make_tree
  127.     make_tree(c1,s,m);
  128.     make_tree(c2,m,e);
  129.     st[cur] = st[c1]+st[c2];
  130. }
  131.  
  132. ///point update . Update a single element of the segment tree
  133. void update_tree(int cur, int s, int e, int x, int val){
  134.    // printf("%d %d %d %d %d\n",cur,s,e,x,val);
  135.     if(s>x || e<=x) return ;
  136.     if(s==x && s==e-1){
  137.         st[cur] = val;
  138. //        printf("Cur: %d , val: %d\n",cur,val);
  139.         return;
  140.     }
  141.     int c1 = (cur<<1),c2 = c1|1,m = (s+e)>>1;
  142.     update_tree(c1,s,m,x,val);
  143.     update_tree(c2,m,e,x,val);
  144.     st[cur] = st[c1]+st[c2];
  145. }
  146.  
  147. ///query in the range [s,e)
  148. void query_tree(int cur, int s, int e, int S, int E){
  149.     if(s >= E || e <= S) {
  150.         qt[cur] = 0;
  151.         return;
  152.     }
  153.     if(s >= S && e <= E) {
  154.         qt[cur] = st[cur];
  155.         return;
  156.     }
  157.     int c1 = (cur<<1),c2=c1|1,m = (s+e)>>1;
  158.     query_tree(c1, s, m, S, E);
  159.     query_tree(c2, m, e, S, E);
  160.     qt[cur] = qt[c1]+qt[c2];
  161. }
  162. // * query_up:
  163. // * It takes two nodes u and v, condition is that v is an ancestor of u
  164. // * We query the chain in which u is present till chain head, then move to next chain up
  165. // * We do that way till u and v are in the same chain, we query for that part of chain and break
  166.  
  167. int query_up(int u, int v){
  168.     if(u==v){ return 0; }
  169.     int uchain,vchain=chainInd[v],ans = 0;
  170. //      uchain & vchain are the chain numbers of u &v respectively!
  171.     while(true){
  172.         uchain = chainInd[u];
  173. //        db(ans);
  174.         if(uchain==vchain){
  175.             if(u==v) break;
  176. //      Both u and v are in the same chain, so we need to query from u to v, update answer and break.
  177. //      We break because we came from u up till v, we are done
  178.            query_tree(1,0,ptr,posInBase[v]+1,posInBase[u]+1);
  179.            ans+=qt[1];
  180.            break;
  181.         }
  182.         query_tree(1,0,ptr,posInBase[chainHead[uchain]],posInBase[u]+1);
  183. //      Above is call to segment tree query function. We do from chainHead of u till u. That is the whole chain from
  184.         ans+=qt[1];
  185.         u = chainHead[uchain];
  186.         u = par[u];
  187.     }
  188.     return ans;
  189. }
  190.  
  191. int query(int u, int v){
  192.     int lca = lca_query(u,v);
  193.     int x = query_up(u,lca);
  194.     int y = query_up(v,lca);
  195.     return (x+y)+Cost[lca];
  196. }
  197.  
  198. /*
  199.  * change:
  200.  * We just need to find its position in segment tree and update it
  201.  */
  202.  
  203. void change(int i, int val){
  204. //    int u = otherEnd[i];
  205.     update_tree(1,0,ptr,posInBase[i],val);
  206. }
  207.  
  208. int main(){
  209.     ios_base::sync_with_stdio(false);
  210.     cin.tie(0);
  211.     int t;
  212.     scanf("%d",&t);
  213.     int tc  = 0;
  214.     memset(chainHead,-1,sizeof(chainHead));
  215.     while(t--){
  216.         scanf("%d",&n);
  217.         for(int i=0; i<n; i++){
  218.             scanf("%d",&Cost[i]);
  219.         }
  220.         for(int i=1; i<=n-1; i++){
  221.             int u,v;
  222.             scanf("%d %d",&u,&v);
  223.             g[u].push_back(v);
  224.             g[v].push_back(u);
  225. //            index[u].push_back(i-1);
  226. //            index[v].push_back(i-1);
  227.         }
  228.         d[0] = 0;
  229.         dfs(0,-1,0);
  230.         lca_init();
  231.         HLD(0,Cost[0],-1);
  232.         make_tree(1,0,ptr);
  233.         printf("Case %d:\n",++tc);
  234.         int q;
  235.         scanf("%d",&q);
  236.         while(q--){
  237.             int a,b,c;
  238.             scanf("%d %d %d",&a,&b,&c);
  239.             if(a==0){
  240.                int ans = query(b,c);
  241.                printf("%d\n",ans);
  242.             }
  243.             else{
  244.                 Cost[b] = c;
  245.                 change(b,c);
  246.             }
  247.         }
  248.         clr();
  249.     }
  250.     return 0;
  251. }
  252.  
  253. /**
  254. 2
  255. 4
  256. 10 20 30 40
  257. 0 1
  258. 1 2
  259. 1 3
  260. 3
  261. 0 2 3
  262. 1 1 100
  263. 0 2 3
  264. 4
  265. 10 20 30 40
  266. 0 1
  267. 1 2
  268. 1 3
  269. 3
  270. 0 2 3
  271. 1 1 100
  272. 0 2 3
  273. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement