const int maxn = 100008 ;
int to[maxn*2] , next[maxn*2] , head[maxn*2] , edge ;
void addedge(int u , int v){
to[edge] = v ; next[edge] = head[u] ; head[u] = edge++ ;
to[edge] = u ; next[edge] = head[v] ; head[v] = edge++ ;
}
int dep[maxn] , tid[maxn] , fa[maxn] , rnk[maxn] , son[maxn] , siz[maxn] , top[maxn] ;
void dfs1(int u , int father , int d){
dep[u] = d ;
fa[u] = father ;
siz[u] = 1 ;
for(int i = head[u] ; i != -1 ; i = next[i]){
int v = to[i] ;
if(v != father){
dfs1(v , u , d+1) ;
siz[u] += siz[v] ;
if(son[u] == -1 || siz[v] > siz[son[u]]) son[u] = v ;
}
}
}
int dfntime ;
void dfs2(int u , int tp){
top[u] = tp ;
tid[u] = ++dfntime ;
rnk[tid[u]] = u ;
if(son[u] == -1) return ;
dfs2(son[u] , tp) ;
for(int i = head[u] ; i != -1 ; i = next[i]){
int v = to[i] ;
if(v != son[u] && v != fa[u]) dfs2(v , v) ;
}
}
void _init(){
memset(head , -1 , sizeof(head)) ;
memset(son , -1 , sizeof(son)) ;
dfntime = 0 ;
edge = 0 ;
}
struct E{
int u , v , w ;
}e[maxn] ;
int a[maxn] , sum[maxn<<2] ;
void up(int t){
sum[t] = sum[t<<1] + sum[t<<1|1] ;
}
void make(int l , int r , int t){
if(l == r){
sum[t] = a[l] ; return ;
}
int m = (l + r) >> 1 ;
make(l , m , t<<1) ;
make(m+1 , r , t<<1|1) ;
up(t) ;
}
void update(int l , int r , int t , int x , int c){
if(l == r){
sum[t] = c ; return ;
}
int m = (l + r) >> 1 ;
if(x <= m) update(l , m , t<<1 , x , c) ;
else update(m+1 , r , t<<1|1 , x , c) ;
up(t) ;
}
int ask(int L , int R , int l , int r , int t){
if(L <= l && r <= R) return sum[t] ;
int m = (l + r) >> 1 ;
int s = 0 ;
if(L <= m) s += ask(L , R , l , m , t<<1) ;
if(R > m) s += ask(L , R , m+1 , r , t<<1|1) ;
return s ;
}
int n ;
int change(int x , int y){
int s = 0 ;
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]]) swap(x , y) ;
s += ask(tid[top[x]] , tid[x] , 1 , n , 1) ;
x = fa[top[x]] ;
}
if(x == y) return s ;
if(dep[x] > dep[y]) swap(x , y) ;
s += ask(tid[x]+1 , tid[y] , 1 , n , 1) ;
return s ;
}
int main(){
int q , s ;
while(scanf("%d%d%d" , &n ,&q ,&s) != EOF){
_init() ;
for(int i = 1 ; i < n ; i++){
scanf("%d%d%d" ,&e[i].u ,&e[i].v ,&e[i].w) ;
addedge(e[i].u , e[i].v) ;
}
dfs1(1 , 0 , 0) ;
dfs2(1 , 1) ;
for(int i = 1 ; i < n ; i++){
if(tid[e[i].u] < tid[e[i].v]) swap(e[i].u , e[i].v) ;
a[tid[e[i].u]] = e[i].w ;
}
make(1 , n , 1) ;
int kd , i , v , w ;
while(q--){
scanf("%d" , &kd) ;
if(kd == 0){
scanf("%d" , &v) ;
printf("%d\n" , change(s , v)) ;
s = v ;
}
else{
scanf("%d%d" , &i , &w) ;
update(1 , n , 1 , tid[e[i].u] , w) ;
}
}
}
return 0 ;
}
poj 2763树链剖分
最新推荐文章于 2022-03-20 20:00:07 发布