wangyibo201026 @ 2023-12-23 12:30:13
代码:
#define genshin
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fir first
#define sec second
#define lep( i, l, r ) for ( int i = ( l ); i <= ( r ); i ++ )
#define rep( i, r, l ) for ( int i = ( r ); i >= ( l ); i -- )
#define gep( i, x ) for ( int i = head[( x )]; i; i = edges[i].next)
char _c; bool _f; template < class T > inline void read ( T &x ) {
_f = 0, x = 0;
while ( _c = getchar (), !isdigit (_c) ){
if ( _c == '-' ) { _f = 1; }
}
while ( isdigit (_c) ){
x = x * 10 + _c - '0', _c = getchar ();
if (_f) { x = -x; }
}
}
const int N = 3e5 + 5;
const int INF = 1145141919810;
int n;
int a[N], p[N];
int head[N], tot;
struct Graph {
int to, w, id, next;
} edges[N << 1];
void add ( int u, int v, int w, int id ) {
tot ++;
edges[tot].to = v;
edges[tot].w = w;
edges[tot].id = id;
edges[tot].next = head[u];
head[u] = tot;
}
int tree[N << 2], tag[N << 2];
void pushup ( int node ) {
tree[node] = max ( tree[node << 1], tree[node << 1 | 1] );
}
void update ( int node, int lt, int rt, int x, int k ) {
if ( x < lt || x > rt ) {
return ;
}
if ( lt == rt && lt == x ) {
tree[node] = k;
// cout << "segment: " << k << '\n';
return ;
}
int mid = lt + rt >> 1;
update ( node << 1, lt, mid, x, k ), update ( node << 1 | 1, mid + 1, rt, x, k );
pushup ( node );
}
int query ( int node, int lt, int rt, int x, int y ) {
if ( y < lt || x > rt ) {
return -INF;
}
if ( x <= lt && rt <= y ) {
return tree[node];
}
int mid = lt + rt >> 1;
return max ( query ( node << 1, lt, mid, x, y ), query ( node << 1 | 1, mid + 1, rt, x, y ) );
}
void dfs ( int x, int fa ) {
for ( int i = head[x]; i; i = edges[i].next ) {
if ( edges[i].to != fa ) {
dfs ( edges[i].to, x );
a[edges[i].to] = edges[i].w;
p[edges[i].id] = edges[i].to;
}
}
}
int cnt;
int dad[N], siz[N], top[N], dep[N], son[N], dfn[N];
void dfs1 ( int x, int fa ) {
dfn[x] = ++ cnt;
dad[x] = fa;
siz[x] = 1;
dep[x] = dep[fa] + 1;
int maxi = -INF;
for ( int i = head[x]; i; i = edges[i].next ) {
if ( edges[i].to != fa ) {
dfs1 ( edges[i].to, x );
siz[x] += siz[edges[i].to];
if ( siz[edges[i].to] > maxi ) {
maxi = siz[edges[i].to];
son[x] = edges[i].to;
}
}
}
}
void dfs2 ( int x, int t ) {
top[x] = t;
update ( 1, 1, n, dfn[x], a[x] );
if ( !son[x] ) {
return ;
}
dfs2 ( son[x], t );
for ( int i = head[x]; i; i = edges[i].next ) {
if ( edges[i].to != dad[x] && edges[i].to != son[x] ) {
dfs2 ( edges[i].to, edges[i].to );
}
}
}
int ask ( int x, int y ) {
int ans = -INF;
while ( top[x] != top[y] ) {
if ( dep[top[x]] < dep[top[y]] ) {
swap ( x, y );
}
ans = max ( ans, query ( 1, 1, n, dfn[top[x]], dfn[x] ) );
x = dad[top[x]];
}
if ( dep[x] > dep[y] ) {
swap ( x, y );
}
ans = max ( ans, query ( 1, 1, n, dfn[x], dfn[y] ) );
return ans;
}
int lca ( int x, int y ) {
while ( top[x] != top[y] ) {
if ( dep[top[x]] < dep[top[y]] ) {
swap ( x, y );
}
x = dad[top[x]];
}
if ( dep[x] > dep[y] ) {
swap ( x, y );
}
return x;
}
void Solve () {
cin >> n;
for ( int i = 1; i < n; i ++ ) {
int u, v, w;
cin >> u >> v >> w;
add ( u, v, w, i ), add ( v, u, w, i );
}
dfs ( 1, 0 );
dfs1 ( 1, 0 );
dfs2 ( 1, 1 );
string op;
while ( cin >> op ) {
if ( op == "CHANGE" ) {
int x, t;
cin >> x >> t;
update ( 1, 1, n, dfn[p[x]], t );
// cout << "change: " << dfn[p[x]] << '\n';
}
else if ( op == "QUERY" ) {
int a, b;
cin >> a >> b;
int tmp = lca ( a, b ), tmp2 = query ( 1, 1, n, dfn[tmp], dfn[tmp] );
update ( 1, 1, n, dfn[tmp], -INF );
cout << ask ( a, b ) << '\n';
update ( 1, 1, n, dfn[tmp], tmp2 );
}
else {
break;
}
// for ( int i = 1; i <= n; i ++ ) {
// cout << query ( 1, 1, n, dfn[i], dfn[i] ) << " ";
// }
// cout << '\n';
}
}
signed main () {
#ifdef genshin
freopen ( "test.in", "r", stdin );
freopen ( "test.out", "w", stdout );
#endif
Solve ();
return 0;
}
感觉代码还算清晰把吧。