洛谷P4315
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 50 ;
int fa[ maxn] , dep[ maxn] , size[ maxn] , son[ maxn] , top[ maxn] , dfn[ maxn] , rid[ maxn] , cnt = 0 ;
ll val[ maxn] ;
vector< int > g[ maxn] ;
struct node {
int l, r;
ll lazy, val, tag;
} t[ maxn * 4 ] ;
void dfs1 ( int u, int f)
{
fa[ u] = f;
dep[ u] = dep[ f] + 1 ;
size[ u] = 1 ;
for ( int i = 0 ; i < g[ u] . size ( ) ; i++ )
{
int v = g[ u] [ i] ;
if ( v != f) {
dfs1 ( v, u) ;
size[ u] + = size[ v] ;
if ( size[ v] > size[ son[ u] ] ) son[ u] = v;
}
}
}
void dfs2 ( int now, int fir)
{
cnt++ ;
top[ now] = fir;
dfn[ now] = cnt;
rid[ dfn[ now] ] = now;
if ( ! son[ now] ) return ;
dfs2 ( son[ now] , fir) ;
for ( int i = 0 ; i < g[ now] . size ( ) ; i++ )
{
int v = g[ now] [ i] ;
if ( v != fa[ now] && v != son[ now] )
dfs2 ( v, v) ;
}
}
void pushup ( int n)
{
t[ n] . val = max ( t[ n<< 1 ] . val, t[ n<< 1 | 1 ] . val) ;
}
void pushdown ( int n)
{
int l = t[ n] . l, r = t[ n] . r;
if ( l == r) return ;
int mid = ( l + r) >> 1 ;
if ( t[ n] . tag != - 1 ) {
t[ n<< 1 ] . tag = t[ n<< 1 | 1 ] . tag = t[ n] . tag;
t[ n<< 1 ] . val = t[ n<< 1 | 1 ] . val = t[ n] . tag;
t[ n<< 1 ] . lazy = t[ n<< 1 | 1 ] . lazy = 0 ;
t[ n] . tag = - 1 ;
}
if ( t[ n] . lazy)
{
t[ n<< 1 ] . lazy + = t[ n] . lazy;
t[ n<< 1 | 1 ] . lazy + = t[ n] . lazy;
t[ n<< 1 ] . val + = t[ n] . lazy;
t[ n<< 1 | 1 ] . val + = t[ n] . lazy;
t[ n] . lazy = 0 ;
}
}
void build ( int n, int l, int r)
{
t[ n] . l = l;
t[ n] . r = r;
t[ n] . lazy = 0 ;
t[ n] . tag = - 1 ;
if ( l == r) {
t[ n] . val = val[ rid[ l] ] ;
return ;
}
int mid = ( l + r) >> 1 ;
build ( n<< 1 , l, mid) ;
build ( n<< 1 | 1 , mid + 1 , r) ;
pushup ( n) ;
}
void update ( int n, int L, int R, ll val, int op)
{
int l = t[ n] . l, r = t[ n] . r;
if ( L <= l && R >= r) {
if ( op == 1 ) {
t[ n] . lazy + = val;
t[ n] . val + = val;
}
else {
t[ n] . val = val;
t[ n] . tag = val;
t[ n] . lazy = 0 ;
}
return ;
}
pushdown ( n) ;
int mid = ( l + r) >> 1 ;
if ( L <= mid) update ( n<< 1 , L, R, val, op) ;
if ( R > mid) update ( n<< 1 | 1 , L, R, val, op) ;
pushup ( n) ;
}
ll query ( int n, int L, int R)
{
int l = t[ n] . l, r = t[ n] . r;
if ( L <= l && R >= r) return t[ n] . val;
pushdown ( n) ;
int mid = ( l + r) >> 1 ;
ll ans = 0 ;
if ( L <= mid) ans = max ( ans, query ( n<< 1 , L, R) ) ;
if ( R > mid) ans = max ( ans, query ( n<< 1 | 1 , L, R) ) ;
pushup ( n) ;
return ans;
}
void subtreechange ( int x, int val, int op)
{
update ( 1 , dfn[ x] , dfn[ x] + size[ x] - 1 , val, op) ;
}
ll subtreequery ( int x)
{
return query ( 1 , dfn[ x] , dfn[ x] + size[ x] - 1 ) ;
}
void linkchange ( int x, int y, int z, int op)
{
while ( top[ x] != top[ y] )
{
if ( dep[ top[ x] ] < dep[ top[ y] ] )
swap ( x, y) ;
update ( 1 , dfn[ top[ x] ] , dfn[ x] , z, op) ;
x = fa[ top[ x] ] ;
}
if ( dep[ x] > dep[ y] ) swap ( x, y) ;
if ( dfn[ x] + 1 <= dfn[ y] ) update ( 1 , dfn[ x] + 1 , dfn[ y] , z, op) ;
}
ll linkquery ( int x, int y)
{
ll ret = 0 ;
while ( top[ x] != top[ y] )
{
if ( dep[ top[ x] ] < dep[ top[ y] ] ) swap ( x, y) ;
ret = max ( ret, query ( 1 , dfn[ top[ x] ] , dfn[ x] ) ) ;
x = fa[ top[ x] ] ;
}
if ( dep[ x] > dep[ y] ) swap ( x, y) ;
if ( dfn[ x] + 1 <= dfn[ y] ) ret = max ( ret, query ( 1 , dfn[ x] + 1 , dfn[ y] ) ) ;
return ret;
}
struct linex {
int x, y, z;
} line[ maxn] ;
int main ( )
{
int n;
scanf ( "%d" , & n) ;
for ( int i = 1 ; i <= n - 1 ; i++ ) {
int u, v, w;
scanf ( "%d%d%d" , & u, & v, & w) ;
g[ u] . push_back ( v) ;
g[ v] . push_back ( u) ;
line[ i] . x = u; line[ i] . y = v; line[ i] . z = w;
}
dfs1 ( 1 , 1 ) ;
for ( int i = 1 ; i <= n - 1 ; i++ )
val[ fa[ line[ i] . x] == line[ i] . y ? line[ i] . x : line[ i] . y] = line[ i] . z;
dfs2 ( 1 , 0 ) ;
build ( 1 , 1 , n) ;
char s[ 20 ] ;
while ( 1 )
{
scanf ( "%s" , s) ;
int u, v, w;
if ( s[ 1 ] == 't' ) break ;
if ( s[ 1 ] == 'a' ) {
scanf ( "%d%d" , & u, & v) ;
printf ( "%lld\n" , linkquery ( u, v) ) ;
}
if ( s[ 1 ] == 'o' ) {
scanf ( "%d%d%d" , & u, & v, & w) ;
linkchange ( u, v, w, 2 ) ;
}
if ( s[ 1 ] == 'd' ) {
scanf ( "%d%d%d" , & u, & v, & w) ;
linkchange ( u, v, w, 1 ) ;
}
if ( s[ 1 ] == 'h' ) {
scanf ( "%d%d" , & u, & w) ;
int z = fa[ line[ u] . x] == line[ u] . y ? line[ u] . x : line[ u] . y;
update ( 1 , dfn[ z] , dfn[ z] , w, 2 ) ;
}
}
return 0 ;
}