比赛 2023级模拟测试1 评测结果 AAAAAAAAAAAA
题目名称 苍天树 最终得分 100
用户昵称 zxhhh 运行时间 9.273 s
代码语言 C++ 内存使用 154.51 MiB
提交时间 2023-09-05 20:53:13
显示代码纯文本
#include <bits/stdc++.h>
#define pb push_back

using namespace std;
const int N = 1e6+5;
typedef long long ll;
int n, m, s, f[N], fa[N][25], dep[N], a[N], b[N]; 
ll k[N];
ll d[N], ans; 
vector <int> e[N]; 
inline int find (int x) { return x == f[x] ? x : f[x] = find(f[x]); }
inline int read () {
    int num = 0; char ch = getchar();
    while (ch <'0' || ch >'9') ch = getchar();
    while (ch >= '0' && ch <= '9') num = (num<<1)+(num<<3)+(ch^48), ch = getchar();
    return num;
}
void dfs (int p, int ft) {
    fa[p][0] = ft; d[p] += d[ft]; dep[p] = dep[ft]+1; 
    for (int i = 1;i < 25;i++) fa[p][i] = fa[fa[p][i-1]][i-1]; 
    for (auto i : e[p]) {
        if (i == ft) continue;
        dfs(i, p); 
    }
}
int LCA (int x, int y) {
    if (dep[x] < dep[y]) swap(x, y); 
    for (int i = 24;~i;i--) {
        if (dep[fa[x][i]] >= dep[y]) x = fa[x][i]; 
    } 
    if (x == y) return x;
    for(int i = 24;~i;i--) {
        if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i]; 
    }
    return fa[x][0]; 
}
void merge (int x, int y) {
    x = find(x); y = find(y); 
    if(x == y) return;
    if(dep[x] > dep[y]) swap(x, y); 
    f[y] = x;
}

int main () {
    freopen("ether_tree.in", "r", stdin); 
    freopen("ether_tree.out", "w", stdout); 
    n = read(); m = read(); a[0] = read();
    memset(k, -1, sizeof(k)); 
    for (int i = 2;i <= n;i++) {
        int ft = read(); d[i] = read(); 
        e[ft].pb(i); 
    }
    dfs(1, 0); 
    for (int i = 1;i <= n;i++) f[i] = i;
    for (int i = 1;i <= m;i++) a[i] = read(), b[i] = read();
    for (int i = 0;i < m;i++) {
        int lca = LCA(a[i], a[i+1]); 
        ans += d[a[i]]+d[a[i+1]]-d[lca]-d[lca]+b[i+1]; 
    }
    for (int i = m;i >= 0;i--) {
        k[a[i]] = max(k[a[i]], ans); 
        if (!i) break;
        ans -= b[i]; int lca = LCA(a[i], a[i-1]); 
        int x = a[i]; 
        while (dep[fa[find(x)][0]] >= dep[lca]) {
            x = find(x); int y = fa[x][0];
            k[y] = max(k[y], ans+d[y]-d[a[i]]);  merge(y, x);
            x = y; 
        } 
        ans += d[lca]-d[a[i]]; 
        int p = find(lca); 
        x = a[i-1]; 
        while (dep[fa[find(x)][0]] >= dep[lca]) {
            x = find(x); int y = fa[x][0];  
            k[y] = max(k[y], ans+d[lca]-d[y]); merge(y, x); 
            x = y;
        }
        ans += d[lca]-d[a[i-1]]; 
    }
    for(int i = 1;i <= n;i++) printf("%lld ", k[i]);
    return 0;
}