- 1 #include<iostream>
- 2 #include<cstring>
- 3 #include<string>
- 4 #include<cmath>
- 5 #include<cstdio>
- 6 #include<algorithm>
- 7 #include<vector>
- 8 #define maxn 200005
- 9 #define MAXN 200005
- 10 #define lson l,mid,rt<<1
- 11 #define rson mid+1,r,rt<<1|1
- 12 using namespace std;
- 13
- 14 long long tree[maxn<<3];
- 15 int n;
- 16 int v[maxn],val[maxn];
- 17 int dep[maxn],fa[maxn],siz[maxn],son[maxn],id[maxn],top[maxn],cnt;
- 18 int co,head[MAXN];
- 19 struct Edge {
- 20 int to, next;
- 21 }edge[MAXN];
- 22 struct E {
- 23 int u, v, c;
- 24 }e[MAXN];
- 25 void addedge(int u, int v) {
- 26 edge[cnt].to = v;
- 27 edge[cnt].next = head[u];
- 28 head[u] = cnt++;
- 29 }
- 30 struct sair{
- 31 int x,y,len;
- 32 }p[maxn];
- 33
- 34 void pushup(int rt){
- 35 tree[rt]=(tree[rt<<1]+tree[rt<<1|1]);
- 36 }
- 37
- 38 void build(int l,int r,int rt){
- 39 if(l==r){
- 40 tree[rt]=0;
- 41 return;
- 42 }
- 43 int mid=(l+r)/2;
- 44 build(lson);
- 45 build(rson);
- 46 pushup(rt);
- 47 }
- 48
- 49 void add(int L,int R,int k,int l,int r,int rt){
- 50 if(L<=l&&R>=r){
- 51 tree[rt]=k;
- 52 return;
- 53 }
- 54 int mid=(l+r)/2;
- 55 if(L<=mid) add(L,R,k,lson);
- 56 if(R>mid) add(L,R,k,rson);
- 57 pushup(rt);
- 58 }
- 59
- 60 long long query(int L,int R,int l,int r,int rt){
- 61 if(L<=l&&R>=r){
- 62 return tree[rt];
- 63 }
- 64 int mid=(l+r)/2;
- 65 long long ans=0;
- 66 if(L<=mid) ans+=query(L,R,lson);
- 67 if(R>mid) ans+=query(L,R,rson);
- 68 pushup(rt);
- 69 return ans;
- 70 }
- 71
- 72 void dfs1(int now,int f,int deep){
- 73 dep[now]=deep;
- 74 siz[now]=1;
- 75 fa[now]=f;
- 76 int maxson=-1;
- 77 for(int i=head[now];~i;i=edge[i].next){
- 78 if(edge[i].to != fa[now]) {
- 79 dfs1(edge[i].to,now,deep+1);
- 80 siz[now]+=siz[edge[i].to];
- 81 if(siz[edge[i].to]>maxson){
- 82 maxson=siz[edge[i].to];
- 83 son[now]=edge[i].to;
- 84 }
- 85 }
- 86 }
- 87 }
- 88
- 89 void dfs2(int now,int topp){
- 90 id[now]=++cnt;
- 91 val[cnt]=v[now];
- 92 top[now]=topp;
- 93 if(!son[now]) return;
- 94 dfs2(son[now],topp);
- 95 for(int i=head[now];~i;i=edge[i].next){
- 96 int vvv = edge[i].to;
- 97 if(vvv==son[now]||vvv==fa[now]) continue;
- 98 dfs2(vvv,vvv);
- 99 }
- 100 }
- 101
- 102 long long qRange(int x,int y){
- 103 int t1 = top[x], t2 = top[y];
- 104 long long res = 0;
- 105 while(t1 != t2) {
- 106 if(dep[t1] < dep[t2]) {
- 107 swap(t1, t2); swap(x, y);
- 108 }
- 109 res += query(id[t1], id[x], 1, n, 1);
- 110 x = fa[t1]; t1 = top[x];
- 111 }
- 112 if(x == y) return res;
- 113 if(dep[x] > dep[y]) swap(x, y);
- 114 return res + query(id[son[x]], id[y], 1, n, 1);
- 115 }
- 116
- 117 void addRange(int x,int y,int k){
- 118 while(top[x]!=top[y]){
- 119 if(dep[top[x]]<dep[top[y]]) swap(x,y);
- 120 add(id[top[x]],id[x],k,1,n,1);
- 121 x=fa[top[x]];
- 122 }
- 123 if(dep[x]>dep[y]) swap(x,y);
- 124 add(id[x],id[y],k,1,n,1);
- 125 }
- 126
- 127 int main(){
- 128 int m,r;
- 129 scanf("%d %d %d",&n,&m,&r);
- 130 memset(head, -1, sizeof head);
- 131 int pos,z,x,y;
- 132 co=0;
- 133 for(int i=1;i<n;i++){
- 134 scanf("%d %d %d",&p[i].x,&p[i].y,&p[i].len);
- 135 addedge(p[i].x,p[i].y);
- 136 addedge(p[i].y,p[i].x);
- 137 }
- 138 cnt=0;
- 139 int xx;
- 140 dfs1(1,0,1);
- 141 dfs2(1,1);
- 142 build(1,n,1);
- 143 for(int i=1;i<n;i++){
- 144 if(dep[p[i].x]<dep[p[i].y]) xx=p[i].y;
- 145 else xx=p[i].x;
- 146 addRange(xx,xx,p[i].len);
- 147 }
- 148 for(int i=1;i<=m;i++){
- 149 scanf("%d %d",&pos,&x);
- 150 if(!pos){
- 151 printf("%lld\n",qRange(x,r));
- 152 r=x;
- 153 }
- 154 else if(pos){
- 155 scanf("%d",&y);
- 156 p[x].len=y;
- 157 if(dep[p[x].x]<dep[p[x].y]) xx=p[x].y;
- 158 else xx=p[x].x;
- 159 addRange(xx,xx,p[x].len);
- 160 }
- 161 }
- 162
- 163 }