求调
查看原帖
求调
916760
Lovely_Sun楼主2024/10/17 18:56
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 5;
vector<int> adj[N]; 
int f[N];
void add_edge(int u, int v) {
    adj[u].push_back(v);
    adj[v].push_back(u);
}
void dfs(int u, int fa) {
    f[u] = fa;
    for (int v : adj[u]) { // 遍历 u 的所有邻接点
        if (v != fa)
            dfs(v, u);
    }
}
int calc(int x) {
    return x * (x + 1) / 2;
}
inline int calc(int a, int b, int c) {
    int x = max((int)1, min(a + 1, (int)ceil(1.0 * (1 - b) / c)));
    if (c < 0)
        return (x - 1) * b + calc(x - 1) * c + (a - x + 1);
    else if (c == 0)
        return a * b;
    else
        return (x - 1) + (a - x + 1) * b + (calc(a) - calc(x - 1)) * c;
}
long long a[N], b[N], c[N];
int p[N], t[N], n;
bool used[N];
int update(int u) {
    if (used[u])
        return 0;
    used[u] = true;
    if (f[u])
        return update(f[u]) + 1;
    return 1;
}
bool check(int x) {
    for (int i = 1; i <= n; ++i) {
        used[i] = false;
        int val = calc(x, b[i], c[i]);
        if (val < a[i])
            return false;

        int l = 1, r = n, ans = -1;
        while (l <= r) {
            int mid = (l + r) >> 1;
            if (val - calc(mid - 1, b[i], c[i]) >= a[i])
                ans = mid, l = mid + 1;
            else
                r = mid - 1;
        }
        t[i] = ans;
    }
    sort(p + 1, p + n + 1, [&](const int &x, const int &y) {
        return t[x] < t[y];
    });
    int res = 0;
    for (int i = 1; i <= n; ++i) {
        res += update(p[i]);
        if (res > t[p[i]])
            return false;
    }
    return true;
}
long long read() {
    long long x = 0, f = 1; 
    char ch = getchar();
    while (!isdigit(ch)) {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (isdigit(ch))
        x = x * 10 + ch - '0', ch = getchar();
    return x * f;
}
signed main() {
    n = read();
    for (int i = 1; i <= n; ++i) {
        a[i] = read(), b[i] = read(), c[i] = read(), p[i] = i;
    }
    for (int i = 2; i <= n; ++i) {
        int u = read(), v = read();
        add_edge(u, v);
    }
    dfs(1, 0);
    
    int l = n, r = 1e9, ans = 1e9;
    while (l <= r)
    {
        int mid = (l + r) >> 1;
        if (check(mid))
        {
            r = mid - 1, ans = mid;
        }
        else
        {
            l = mid + 1;
        }
    }
    cout << ans;
    return 0;
}

RT

2024/10/17 18:56
加载中...