Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- using namespace std;
- #define int long long
- const int N = 1e5+11;
- const int LOGN = log2(N);
- int parent[N];
- int depth[N];
- int dp[N][LOGN+1];
- vector<pair<int,int>> graph[N];
- pair<int,pair<int,int>> edge[N];
- int dfsorder[N];
- int st[N];
- int ed[N];
- int sz[N];
- int Time;
- int tree[4*N];
- void dfs(int u,int par){
- dfsorder[Time] = u;
- st[u] = Time;
- ++Time;
- if(u!=1){
- dp[u][0] = par;
- for(int i=1;i<=LOGN;++i)
- dp[u][i] = dp[dp[u][i-1]][i-1];
- }
- for(auto x:graph[u]){
- int v = x.first;
- int w = x.second;
- if(v==par)
- continue;
- sz[v] = sz[u] + w;
- parent[v] = u;
- depth[v] = depth[u] + 1;
- dfs(v,u);
- }
- ed[u] = Time;
- }
- int lca(int u, int v) {
- if (depth[u] < depth[v]) swap(u, v);
- for(int i=LOGN;i>=0;i--)//to make them on same level after this depth[u] = depth[v]
- if(depth[dp[u][i]] >= depth[v])
- u = dp[u][i];
- if(u==v)
- return v;
- for (int i=LOGN;i>=0;i--)
- if(dp[u][i]!=dp[v][i]){
- u = dp[u][i];
- v = dp[v][i];
- }
- return dp[u][0];
- }
- void update(int low,int high,int idx1,int idx2,int value,int pos){
- if(low>idx2 || high<idx1)
- return;
- if(low>=idx1 && high<=idx2){
- tree[pos]+=value;
- return;
- }
- int mid = (low+high)/2;
- update(low,mid,idx1,idx2,value,2*pos);
- update(mid+1,high,idx1,idx2,value,2*pos+1);
- }
- int query(int low,int high,int idx,int pos){
- if(low>idx || high<idx)
- return 0;
- if(low==high)
- return tree[pos];
- int mid = (low+high)/2;
- return (query(low,mid,idx,2*pos) + query(mid+1,high,idx,2*pos+1) + tree[pos]);
- }
- int32_t main(){
- ios::sync_with_stdio(false);
- cin.tie(0);
- cout.tie(0);
- parent[1] = 1;
- depth[1] = 1;
- int n;
- cin>>n;
- for(int i=1;i<n;++i){
- int u,v,w;
- cin>>u>>v>>w;
- graph[u].push_back({v,w});
- graph[v].push_back({u,w});
- edge[i] = {w,{u,v}};
- }
- dfs(1,-1);
- int q;
- cin>>q;
- while(q--){
- int type;
- cin>>type;
- if(type==1){
- int i,c;
- cin>>i>>c;
- int u = edge[i].second.first;
- int v= edge[i].second.second;
- int w = edge[i].first;
- if(parent[u]!=v)
- swap(u,v);
- int change = c - w;
- edge[i].first = c;
- int idx1 = st[u];
- int idx2 = ed[u];
- --idx2;
- update(1,n,idx1,idx2,change,1);
- }
- else{
- int u,v;
- cin>>u>>v;
- int par = lca(u,v);
- 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;
- }
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment