• F


    //#include<bits/stdc++.h>
    //#pragma comment(linker, "/STACK:1024000000,1024000000") 
    #include<stdio.h>
    #include<algorithm>
    #include<queue>
    #include<string.h>
    #include<iostream>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<iomanip>
    using namespace std;
    #define ll long long
    #define pb push_back
    const int maxn=1e6+7;
    const int inf=0x3f3f3f3f;
    
    struct EDGE{
    	int u,v,val,next;
    }G[maxn<<1];
    int tot;int head[maxn];
    void init(){
    	memset(head,-1,sizeof head);tot=0;
    }
    void addedge(int u,int v,int w){
    	tot++;G[tot]={u,v,w,head[u]};head[u]=tot;
    }
    
    int vs[maxn<<1];
    int in[maxn],out[maxn];
    int tim; 
    int dep[maxn<<1];
    int id[maxn];
    int pre[maxn];
    void dfs(int u,int fa,int d){
    	pre[u]=fa;
    	id[u]=++tim;vs[tim]=u;dep[tim]=d;
    	in[u]=tim;out[u]=tim;
    	for(int i=head[u];~i;i=G[i].next){
    		EDGE e=G[i];
    		if(e.v==fa)continue;
    		dfs(e.v,u,d+e.val);
    		vs[++tim]=u;dep[tim]=d;out[u]=tim;
    	}
    }
    
    struct node{
    	int fa;		//区间内公共祖先
    	int mindep;
    	int add;	//lazy
    }ST[maxn<<2];
    void pushdown(int rt){
    	if(ST[rt].add){
    		ST[rt<<1].mindep+=ST[rt].add;ST[rt<<1|1].mindep+=ST[rt].add;
    		ST[rt<<1].add+=ST[rt].add;ST[rt<<1|1].add+=ST[rt].add;
    		ST[rt].add=0;
    	}
    }
    void pushup(int rt){
    	if(ST[rt<<1].mindep<=ST[rt<<1|1].mindep){
    		ST[rt].mindep=ST[rt<<1].mindep;
    		ST[rt].fa=ST[rt<<1].fa;
    	}else{
    		ST[rt].mindep=ST[rt<<1|1].mindep;
    		ST[rt].fa=ST[rt<<1|1].fa;
    	}
    }
    void build(int l,int r,int rt){
    	if(l==r){
    		ST[rt].mindep=dep[l];
    		ST[rt].fa=vs[l];
    		ST[rt].add=0;
    		return;
    	}
    	ST[rt].add=0;
    	int m=l+r>>1;
    	build(l,m,rt<<1);
    	build(m+1,r,rt<<1|1);
    	pushup(rt);
    }
    void update(int a,int b,int c,int l,int r,int rt){
    	if(a<=l&&b>=r){
    		ST[rt].mindep+=c;
    		ST[rt].add+=c;
    		return;
    	}
    	pushdown(rt);
    	int m=l+r>>1;
    	if(a<=m)update(a,b,c,l,m,rt<<1);
    	if(b>m)update(a,b,c,m+1,r,rt<<1|1);
    	pushup(rt);
    }
    node query(int a,int b,int l,int r,int rt){	//查询a-b内的祖先
    	//cout<<a<<" "<<b<<" "<<l<<" "<<r<<endl;
    	if(a<=l&&b>=r){
    		return ST[rt];
    	}
    	pushdown(rt);
    	int m=l+r>>1;
    	node n2={0,inf,0},n1={0,inf,0};
    	if(a<=m)n1=query(a,b,l,m,rt<<1);
    	if(b> m)n2=query(a,b,m+1,r,rt<<1|1);
    	if(n1.mindep<n2.mindep){return n1;}
    	else return n2;
    }
    
    int main(){
    	int n,q,s;
    	while(~scanf("%d%d%d",&n,&q,&s)){
    		init();
    		for(int i=1;i<n;i++){
    			int u,v,w;
    			scanf("%d%d%d",&u,&v,&w);
    			//if(u>v)swap(u,v);
    			addedge(u,v,w);
    			addedge(v,u,w);
    		}
    
    		int now=s;
    		tim=0;
    		dep[s]=0;	
    		dfs(s,s,0);
    		
    		build(1,tim,1);
    	
    		for(int i=1;i<=q;i++){
    			int kind;int a,b;
    			scanf("%d",&kind);
    			if(kind){			//改边
    				scanf("%d%d",&a,&b);
    				a=2*a-1;
    				int flag=0;
    				if(pre[G[a].v]==G[a].u){flag=1;}
    				else a++;
    				
    				EDGE e=G[a];
    
    				int plus=b-e.val;
    
    				update(in[e.v],out[e.v],plus,1,tim,1);
    				if(flag){
    					G[a].val=b;
    					G[a+1].val=b;
    				}else{
    					G[a].val=b;
    					G[a-1].val=b;
    				}
    				//for(int i=1;i<=tim;i++){
    				//	cout<<vs[i]<<"ss"<<endl;
    				//}
    				
    			}else{
    				scanf("%d",&a);
    				//cout<<now<<" "<<a<<endl;
    				
    				node anc=
    					query(min(id[a],id[now]),max(id[now],id[a]),1,tim,1);
    
    				node n1,n2;
    				n1=query(id[now],id[now],1,tim,1);
    				n2=query(id[a],id[a],1,tim,1);
    
    				int ans=n1.mindep+n2.mindep-anc.mindep*2;
    				//cout<<n1.mindep<<" "<<n2.mindep<<" "<<anc.mindep<<endl;
    				//cout<<n1.fa<<" "<<n2.fa<<" "<<anc.fa<<endl;
    				printf("%d
    ",ans);
    				now=a;
    			}
    		}
    	}
    }
    
    /*
     3 100 2
     1 2 6
     1 3 5
     1 1 4
     0 1
     */

    核心就是vs序列存下的in[u],out[u]的中间段只有u的子树

    做法肯定不是最优的,因为检查每个节点的深度我都用到了线段树查询,慢了3倍

    换上树状数组肯定能更快,但我懒得学。。

    双向边的编号修改难死我了。。。还好想出办法解决了

    (其实是别人的代码我看不懂

  • 相关阅读:
    Swift学习-Property
    Swift学习-protocol
    Swift学习-Class
    Swift学习-Enumerate、Structure
    iOS“此时无法下载应用”解决办法
    iTunes Connect用户职能与权限
    TestFlight Beta Testing 开发指南中英对照
    梳理一下KVC
    mac下使用github 上传代码(转)
    运用Runtime全局修改UILabel的默认字体
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611301.html
Copyright © 2020-2023  润新知