rt,在第一个 Max 处卡住了。
#include <bits/stdc++.h>
using namespace std;
#define int long long
inline int Read() {
int x = 0 , f = 1;
char c = getchar();
for( ; c < '0' || c > '9' ; c = getchar() ) f ^= ( c == '-' );
for( ; c >= '0' && c <= '9' ; c = getchar() ) x = ( x << 3 ) + ( x << 1 ) + ( c ^ 48 );
return f ? x : -x;
}
#define NONE -1145141919810
struct SMT {
private:
struct Node {
Node *L , *R;
int l , r;
int cover , add , mx;
Node( int l , int r ) : L(NULL),R(NULL),l(l),r(r),cover(NONE),add(0),mx(INT_MIN) {}
int mid() { return l + ( r - l ) / 2 ; }
int len() { return r - l + 1 ; }
void PushUp() {
mx = max( L->mx , R->mx );
}
void PushDown() {
if( cover != NONE ) {
L->add = R->add = 0;
L->mx = R->mx = cover;
L->cover = R->cover = cover;
cover = NONE;
}
L->add += add;
R->add += add;
L->mx += add , R->mx += add;
add = 0;
}
};
public:
Node *root;
void Build( int l , int r , Node *&p , int a[] ) {
p = new Node( l , r );
if( l == r ) {
p->mx = a[ l ];
return;
}
Build( l , p->mid() , p->L , a );
Build( p->mid() + 1 , r , p->R , a );
p->PushUp();
}
void Add( int x , int y , int v , Node *p ) {
if( x <= p->l && p->r <= y ) {
p->mx += v;
p->add += v;
return;
}
p->PushDown();
if( x <= p->mid() ) Add( x , y , v , p->L );
if( y > p->mid() ) Add( x , y , v , p->R );
p->PushUp();
}
void Assign( int x , int y , int v , Node *p ) {
if( x <= p->l && p->r <= y ) {
p->mx = v;
p->add = 0;
p->cover = v;
return;
}
p->PushDown();
if( x <= p->mid() ) Assign( x , y , v , p->L );
if( y > p->mid() ) Assign( x , y , v , p->R );
p->PushUp();
}
int GetMax( int x , int y , Node *p ) {
if( x <= p->l && p->r <= y ) {
return p->mx;
}
p->PushDown();
int ans = INT_MIN;
if( x <= p->mid() ) ans = max( ans , GetMax( x , y , p->L ) );
if( y > p->mid() ) ans = max( ans , GetMax( x , y , p->R ) );
return ans;
}
} seg;
const int _ = 1e5 + 5;
struct Edge { int v , w , nxt ; } e[_*2];
int head[_] , ecnt;
void Add( int u , int v , int w = 1 ) { e[ ++ecnt ] = Edge{ v , w , head[ u ] } ; head[ u ] = ecnt ; }
int dep[_] , fa[_] , siz[_] , son[_] , dfn[_] , top[_];
int cnt;
void DFS1( int x ) {
dep[ x ] = dep[ fa[ x ] ] + 1;
siz[ x ] = 1;
for( int i = head[ x ] ; i ; i = e[ i ].nxt ) {
int y = e[ i ].v;
if( !dep[ y ] ) {
fa[ y ] = x;
DFS1( y );
siz[ x ] += siz[ y ];
if( siz[ y ] > siz[ son[ x ] ] ) {
son[ x ] = y;
}
}
}
}
void DFS2( int x ) {
dfn[ x ] = ++cnt;
if( son[ x ] ) {
top[ son[ x ] ] = top[ x ];
DFS2( son[ x ] );
}
for( int i = head[ x ] ; i ; i = e[ i ].nxt ) {
int y = e[ i ].v;
if( !top[ y ] ) {
top[ y ] = y;
DFS2( y );
}
}
}
void ChangePath( int x , int y , int v ) {
while( top[ x ] != top[ y ] ) {
if( dep[ top[ x ] ] < dep[ top[ y ] ] ) swap( x , y );
seg.Assign( dfn[ top[ x ] ] , dfn[ x ] , v , seg.root );
x = fa[ top[ x ] ];
}
if( dep[ x ] > dep[ y ] ) swap( x , y );
if( x != y ) seg.Assign( dfn[ x ] + 1 , dfn[ y ] , v , seg.root );
}
void AddPath( int x , int y , int v ) {
while( top[ x ] != top[ y ] ) {
if( dep[ top[ x ] ] < dep[ top[ y ] ] ) swap( x , y );
seg.Add( dfn[ top[ x ] ] , dfn[ x ] , v , seg.root );
x = fa[ top[ x ] ];
}
if( dep[ x ] > dep[ y ] ) swap( x , y );
if( x != y ) seg.Add( dfn[ x ] + 1 , dfn[ y ] , v , seg.root );
}
int QueryPath( int x , int y ) {
int ans = LLONG_MIN;
while( top[ x ] != top[ y ] ) {
if( dep[ top[ x ] ] < dep[ top[ y ] ] ) swap( x , y );
ans = max( ans , seg.GetMax( dfn[ top[ x ] ] , dfn[ x ] , seg.root ) );
x = fa[ top[ x ] ];
}
if( dep[ x ] > dep[ y ] ) swap( x , y );
if( x != y ) ans = max( ans , seg.GetMax( dfn[ x ] + 1 , dfn[ y ] , seg.root ) );
return ans;
}
int n;
int u[_] , v[_] , w[_] , a[_] , b[_];
signed main() {
n = Read();
for( int i = 1 ; i < n ; i++ ) {
u[ i ] = Read() , v[ i ] = Read() , w[ i ] = Read();
}
DFS1( 1 ) , fa[ 1 ] = 1 , top[ 1 ] = 1 , DFS2( 1 );
for( int i = 1 ; i <= n ; i++ ) {
if( dep[ u[ i ] ] > dep[ v[ i ] ] ) {
a[ dfn[ u[ i ] ] ] = w[ i ];
} else {
a[ dfn[ v[ i ] ] ] = w[ i ];
}
}
seg.Build( 1 , n , seg.root , a );
while( 1 ) {
string str;
cin >> str;
if( str == "Stop" ) break;
if( str == "Change" ) {
int k = Read() , w = Read();
seg.Assign( dep[ u[ k ] ] > dep[ v[ k ] ] ? dfn[ u[ k ] ] : dfn[ v[ k ] ] , dep[ u[ k ] ] > dep[ v[ k ] ] ? dfn[ u[ k ] ] : dfn[ v[ k ] ] , w , seg.root );
} if( str == "Cover" ) {
int u = Read() , v = Read() , w = Read();
ChangePath( u , v , w );
} if( str == "Add" ) {
int u = Read() , v = Read() , w = Read();
AddPath( u , v , w );
} if( str == "Max" ) {
int x = Read() , y = Read();
printf( "%lld\n" , QueryPath( x , y ) );
}
}
return 0;
}