ydvsahil

LCA

May 30th, 2020
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.83 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define int long long
  4. const int N = 1e5+11;
  5. const int LOGN = log2(N);
  6. int parent[N];
  7. int depth[N];
  8. int dp[N][LOGN+1];
  9. vector<pair<int,int>> graph[N];
  10. pair<int,pair<int,int>> edge[N];
  11. int dfsorder[N];
  12. int st[N];
  13. int ed[N];
  14. int sz[N];
  15. int Time;
  16. int tree[4*N];
  17. void dfs(int u,int par){
  18.     dfsorder[Time] = u;
  19.     st[u] = Time;
  20.     ++Time;
  21.     if(u!=1){
  22.         dp[u][0] = par;
  23.         for(int i=1;i<=LOGN;++i)
  24.             dp[u][i] = dp[dp[u][i-1]][i-1];
  25.     }
  26.     for(auto x:graph[u]){
  27.         int v = x.first;
  28.         int w = x.second;
  29.         if(v==par)
  30.             continue;
  31.         sz[v] = sz[u] + w;
  32.         parent[v] = u;
  33.         depth[v] = depth[u] + 1;
  34.         dfs(v,u);
  35.     }
  36.     ed[u] = Time;
  37. }
  38. int lca(int u, int v) {
  39.     if (depth[u] < depth[v]) swap(u, v);
  40.  
  41.     for(int i=LOGN;i>=0;i--)//to make them on same level after this depth[u] = depth[v]
  42.         if(depth[dp[u][i]] >= depth[v])
  43.             u = dp[u][i];
  44.     if(u==v)
  45.         return v;
  46.     for (int i=LOGN;i>=0;i--)
  47.         if(dp[u][i]!=dp[v][i]){
  48.             u = dp[u][i];
  49.             v = dp[v][i];
  50.         }
  51.     return dp[u][0];
  52. }
  53. void update(int low,int high,int idx1,int idx2,int value,int pos){
  54.     if(low>idx2 || high<idx1)
  55.         return;
  56.     if(low>=idx1 && high<=idx2){
  57.         tree[pos]+=value;
  58.         return;
  59.     }
  60.     int mid = (low+high)/2;
  61.     update(low,mid,idx1,idx2,value,2*pos);
  62.     update(mid+1,high,idx1,idx2,value,2*pos+1);
  63. }
  64. int query(int low,int high,int idx,int pos){
  65.     if(low>idx || high<idx)
  66.         return 0;
  67.     if(low==high)
  68.         return tree[pos];
  69.     int mid = (low+high)/2;
  70.     return (query(low,mid,idx,2*pos) + query(mid+1,high,idx,2*pos+1) + tree[pos]);
  71. }
  72. int32_t main(){
  73.     ios::sync_with_stdio(false);
  74.     cin.tie(0);
  75.     cout.tie(0);
  76.     parent[1] = 1;
  77.     depth[1] = 1;
  78.     int n;
  79.     cin>>n;
  80.     for(int i=1;i<n;++i){
  81.         int u,v,w;
  82.         cin>>u>>v>>w;
  83.         graph[u].push_back({v,w});
  84.         graph[v].push_back({u,w});
  85.         edge[i] = {w,{u,v}};
  86.     }
  87.     dfs(1,-1);
  88.     int q;
  89.     cin>>q;
  90.     while(q--){
  91.         int type;
  92.         cin>>type;
  93.         if(type==1){
  94.             int i,c;
  95.             cin>>i>>c;
  96.             int u = edge[i].second.first;
  97.             int v= edge[i].second.second;
  98.             int w = edge[i].first;
  99.             if(parent[u]!=v)
  100.                 swap(u,v);
  101.             int change = c - w;
  102.             edge[i].first = c;
  103.             int idx1 = st[u];
  104.             int idx2 = ed[u];
  105.             --idx2;
  106.             update(1,n,idx1,idx2,change,1);
  107.         }
  108.         else{
  109.             int u,v;
  110.             cin>>u>>v;
  111.             int par = lca(u,v);
  112.             cout<<(sz[u]+query(1,n,st[u],1)+sz[v]+query(1,n,st[v],1)-2*(sz[par]+query(1,n,st[par],1)))<<endl;
  113.         }
  114.     }
  115.     return 0;
  116. }
Add Comment
Please, Sign In to add comment