社区讨论

比答案大1且全部使用int128

P9755[CSP-S 2023] 种树参与者 2已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@mhizsoec
此快照首次捕获于
2025/11/03 18:23
4 个月前
此快照最后确认于
2025/11/03 18:23
4 个月前
查看原帖
CPP
#include <bits/stdc++.h>
#define int __int128
#define endl '\n'
#define pii pair<int, int>
#define fi first
#define se second
#define rep(x, y, z) for (int x = (y); x <= (z); ++x)
#define per(x, z, y) for (int x = (z); x >= (y); --x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()
using namespace std;
constexpr int maxn = 2e5 + 5, inf = 1e18;
mt19937 rnd(20070407);
int a[maxn], b[maxn], c[maxn], n; vector<int> g[maxn];
pii t[maxn];
struct DSU {
    int fa[maxn];
    void init() {rep(i, 1, n) fa[i] = i;}
    inline int find(int u) {return fa[u] == u ? u : fa[u] = find(fa[u]);}
    void merge(int u, int v) {
        u = find(u), v = find(v);
        if (u == v) return;
        fa[v] = u;
    }
} dsu;
int fa[maxn];
inline void dfs(int p) {
    for (auto v : g[p]) if (v != fa[p]) {
        fa[v] = p;
        dfs(v);
    }
}
using i128 = __int128;
bool check(int mid) {
    rep(i, 1, n) {
        if (c[i] == 0) {
            t[i] = {mid - (a[i] + b[i] - 1) / b[i] + 1, i};
            continue;
        }
        if (c[i] < 0) {
            int L = 0, R = n, s = min(mid, b[i] / (-c[i]));
            if (b[i] % (-c[i]) == 0) --s;
            while (L < R) {
                int md = (L + R + 1) >> 1;
                int val = 0;
                if (md <= s) val = (i128)(b[i] + (i128)md * c[i] + b[i] + (i128)s * c[i]) * (s - md + 1) / 2;
                if (a[i] - val <= mid - max(s, md - 1)) L = md;
                else R = md - 1;
            }
            t[i] = {L, i};
        }
        if (c[i] > 0) {
            int L = 0, R = n;
            while (L < R) {
                int md = (L + R + 1) >> 1;
                i128 val = (i128)(b[i] + (i128)md * c[i] + b[i] + (i128)mid * c[i]) * (mid - md + 1) / 2;
                if (val >= a[i]) L = md;
                else R = md - 1;
            }
            t[i] = {L, i};
        }
    }
    rep(i, 1, n) if (t[i].fi <= 0) return false;
    sort(t + 1, t + 1 + n);
    dsu.init();
    int cur = 1;
    rep(i, 1, n) {
        int p = dsu.find(t[i].se);
        if (p == 1) continue;
        while (p != 1) {
            dsu.merge(fa[p], p);
            p = dsu.find(p);
            ++cur;
        }
        if (cur > t[i].fi) return false;
    }
    return true;
}
namespace{
	using lll=__int128;
	constexpr lll LLL_MAX=((lll)(0x7fffffffffffffff)<<64)+(lll)(0xffffffffffffffff);
	istream& operator>>(istream &is,lll &x){
		string s; bool neg=0;
		is>>s; x=0;
		for(auto c:s) (c=='-'?neg=1:x=x*10+(c-'0'));
		if(neg) x=-x;
		return is;
	}
	ostream& operator<<(ostream &os,lll x){
		if(x==0) return os<<0;
		string s; bool neg=(x<0?(x=-x,1):0);
		while(x) s.push_back(x%10+'0'),x/=10;
		reverse(s.begin(),s.end());
		return (neg?os<<'-':os)<<s;
	}
}
signed main() {
    // freopen("tree3.in","r",stdin);
    cin >> n;
    rep(i, 1, n) cin >> a[i] >> b[i] >> c[i];
    rep(i, 1, n - 1) {
        int u, v; cin >> u >> v;
        g[u].push_back(v), g[v].push_back(u);
    }
    dfs(1);
    int L = n, R = 1e9;
    while (L < R) {
        int mid = (L + R) >> 1;
        if (check(mid)) R = mid;
        else L = mid + 1;
    }
    cout << L << endl;
    return 0;
}

回复

4 条回复,欢迎继续交流。

正在加载回复...