The 15th Jilin Provincial Collegiate Programming Contest D. Rush Morning 线段树动态维护树直径

传送门

#include <iostream>
#include <cstring>
#include <iomanip>
#include <algorithm>
#include <stack>
#include <queue>
#include <numeric>
#include <cassert>
#include <bitset>
#include <cstdio>
#include <vector>
#include <unordered_set>
#include <cmath>
#include <map>
#include <unordered_map>
#include <set>
#include <deque>

#define all(a) a.begin(), a.end()
#define cnt0(x) __builtin_ctz(x)
#define endl '\n'
#define itn int
#define ll long long
#define ull unsigned long long
#define rep(i, a, b) for(int i = a;i <= b; i ++)
#define per(i, a, b) for(int i = a;i >= b; i --)
#define cntone(x) __builtin_popcount(x)
#define db double
#define fs first
#define se second
#define AC main(void)
#define HYS std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
typedef std::pair<int, int > PII;
typedef std::pair<int, std::pair<int, int>> PIII;
typedef std::pair<ll, ll> Pll;
typedef std::pair<double, double> PDD;
using ld = double long;

const int MOD = 1e9 + 7;
const long double eps = 1e-9;
int d1[] = {0, 0, 1, -1};
int d2[] = {1, -1, 0, 0};
const int N = 4e5 + 10, M = 8e5 + 10;
const int INF = 0x3f3f3f3f;
int n, m;
int _ = 1;
int a[M];

int h[N], ne[M], e[M], idx, cnt ,dfn[M], ddfn[M], out[M], dep[M];
ll dis[M], w[M];

struct node{
    int l, r;
	ll mx, mn;//mn就是LCA
	ll lm, rm;//缺少左端点和缺少右端点时的最大值
    ll lazy, ans;
}tr[N * 4];

void add(int a, int b, ll c){
    ne[idx] = h[a], e[idx] = b, w[idx] = c, h[a] = idx ++;
}

void dfs(int u, int fa, ll dist){
	dfn[++ cnt] = u;
	ddfn[u] = cnt;
	dis[u] = dist;
	for(int i = h[u]; ~i; i = ne[i]){
		int j = e[i];
		if(j == fa)	continue;
		dep[j] = dep[u] + 1;
		dfs(j, u, dist + w[i]);
		dfn[++ cnt] = u;
	}
	out[u] = cnt;
}

void pushup(int u){
    tr[u].mx = std::max(tr[u << 1].mx, tr[u << 1 | 1].mx);
	tr[u].mn = std::min(tr[u << 1].mn, tr[u << 1 | 1].mn);
	tr[u].lm = std::max({tr[u << 1].lm, tr[u << 1 | 1].lm, tr[u << 1 | 1].mx - tr[u << 1].mn * 2});
	tr[u].rm = std::max({tr[u << 1].rm, tr[u << 1 | 1].rm, tr[u << 1].mx - tr[u << 1 | 1].mn * 2});
	tr[u].ans = std::max({tr[u << 1].ans, tr[u << 1 | 1].ans, tr[u << 1].rm + tr[u << 1 | 1].mx, tr[u << 1 | 1].lm + tr[u << 1].mx});
}


void pushdown(int u){
    if(tr[u].lazy){
        tr[u << 1].lm -= tr[u].lazy;
        tr[u << 1].rm -= tr[u].lazy;
        tr[u << 1].mn += tr[u].lazy;
        tr[u << 1].mx += tr[u].lazy;
        tr[u << 1].lazy += tr[u].lazy;
		tr[u << 1 | 1].lm -= tr[u].lazy;
        tr[u << 1 | 1].rm -= tr[u].lazy;
        tr[u << 1 | 1].mn += tr[u].lazy;
        tr[u << 1 | 1].mx += tr[u].lazy;
        tr[u << 1 | 1].lazy += tr[u].lazy;
        tr[u].lazy = 0;
    }
}

void build_tree(int u, int l, int r){
    tr[u] = {l, r};
    if(l == r){
		tr[u].mx = tr[u].mn = dis[dfn[l]];
		tr[u].lm = tr[u].rm = -dis[dfn[l]];
    	return ;
    }  
    int mid = l + r >> 1;
    build_tree(u << 1, l, mid);
    build_tree(u << 1 | 1, mid + 1, r);
	pushup(u);
}

void modify(int u, int l, int r, ll k){
    if(tr[u].l >= l && tr[u].r <= r){
        tr[u].lazy += k;
        tr[u].lm -= k;
        tr[u].rm -= k;
        tr[u].mn += k;
        tr[u].mx += k;
        return ;
    }
    pushdown(u);

    int mid = tr[u].l + tr[u].r >> 1;
    if(l <= mid)    modify(u << 1, l, r, k);
    if(r > mid) modify(u << 1 | 1, l, r, k);

    pushup(u);
}

void solve(){
	std::cin >> n;
	memset(h, -1, sizeof h);
	for(int i = 1; i < n; i ++){
		int a, b;
		ll c;
		std::cin >> a >> b >> c;
		add(a, b, c);
		add(b, a, c);
	}

	dfs(1, -1, 0);
    build_tree(1, 1, cnt);
	std::cin >> m;
	while(m --){
		int a, b;
		ll c;
		std::cin >> a >> b >> c;
		if(dep[a] > dep[b])	std::swap(a, b);
		ll get = c - (dis[b] - dis[a]);
		modify(1, ddfn[b], out[b], get);
		std::cout << tr[1].ans << '\n';
		modify(1, ddfn[b], out[b], -get);
	}
}

signed AC{
    HYS
    
	//std::cin >> _;
	while(_ --)
        solve();
    
    return 0;
}
posted @ 2023-05-23 22:20  春始于雪之下  阅读(43)  评论(0编辑  收藏  举报