原代码(用了int128)
//
// Created by 32373 on 2023/10/24.
//
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#define md1 ((l+r) >> 1)
using namespace std;
typedef __int128 ll;
const long long N=1e5+3;
ll a[N], b[N], c[N];
ll ad[N];
struct p{
vector<ll>ut;
};
struct nd{
ll v, ps;
bool operator < (const nd &b)const{
return this->v < b.v;
}
bool operator > (const nd &b)const{
return this->v > b.v;
}
};
p ps[N];
ll dp[N], fa[N];
void dfs(ll nw, ll pr){
fa[nw] = pr;
dp[nw] = dp[pr] + 1;
for (ll t:ps[nw].ut){
if (t == pr)continue;
dfs(t, nw);
}
}
long long n;
ll eta[N]; // 每个点最晚种树天数
void ck(ll d){ // 给定总天数,求每个点最晚的种树天数
for (ll x=1;x<=n;++x){
ll l=1, r=d;
while (l < r){
ll mid=md1;
if (c[x] >= 0) {
ll st = b[x] + d * c[x];
if (mid * st - (mid * (mid - 1)) / 2 * c[x] >= a[x]) {
r = mid;
} else {
l = mid+1;
}
} else {
ll cp= d - ceil((long double)b[x] / (long double)-c[x]) + 1;
ll st=b[x] + (d-cp) * c[x];
if (mid <= cp){
if (mid >= a[x]){
r = mid;
} else {
l = mid+1;
}
} else {
ll val=cp;
val += (mid - cp) * st - (mid - cp) * (mid - cp - 1) / 2 * c[x];
if (val >= a[x]){
r = mid;
} else {
l = mid+1;
}
}
}
}
eta[x] = d - l + 1;
}
}
ll cnt2, mn;
bool iv=false;
ll up(ll p){ // 模拟种树
if (ad[p])return ad[p];
if (p == 1){
ad[p] = ++cnt2;
return ad[p];
}
up(fa[p]);// 向上递归直到找到根节点或第一个已经种过的点
ll x=p;
if (c[x] < 0){ // 检查求出来的最晚种树日期合不合法
ll res, u1 = ceil((long double)b[x] / (long double)-c[x]);
if (mn < u1){
res = (mn) * (b[x] + c[x]) + (mn) * (mn-1) / 2 * c[x];
} else {
res = (u1-1) * (b[x] + c[x]) + (u1-1) * (u1-2) / 2 *c[x] + (mn - u1 + 1);
}
if (res < a[x]){
iv = true; // 不合法
}
} else {
ll res = (mn) * (b[x] + c[x]) + (mn) *(mn-1) / 2 *c[x];
if (res < a[x]){
iv = true; // 不合法
}
}
ad[p] = ++cnt2;
return ad[p];
}
ll cnt;
struct pri{
ll no, rd;
bool operator < (const pri &b)const{
return this->rd < b.rd;
}
bool operator > (const pri &b)const{
return this->rd > b.rd;
}
};
int main(){
long long ta, tb, tc;
// freopen("E:\\tree2.in", "r", stdin);
scanf("%lld", &n);
for (ll x=1;x<=n;++x){
scanf("%lld %lld %lld", &ta, &tb, &tc);
a[x] = ta, b[x] = tb, c[x] = tc;
}
for (ll x=1;x<n;++x){
scanf("%lld %lld", &ta, &tb);
ps[ta].ut.push_back(tb);
ps[tb].ut.push_back(ta);
}
ll l=1, r=1e9;
// ck(51);
// puts("fuckccf");
dfs(1, 0); // O(n)
vector<pri>prs;
while (l < r){ // 二分答案
prs.clear();
mn = md1;
ck(md1);
for (ll x=1;x<=n;++x){ // O(n)
prs.push_back((pri){x, eta[x]});
ad[x] = 0;
}
sort(prs.begin(), prs.end()); // O(nlogn)
cnt=0;
cnt2=0;
for (ll x=0;x<n;++x){ // O(n)
up(prs[x].no);
}
bool f=false;
for (ll x=1;x<=n;++x){
if (ad[x] > eta[x]){
f=true;
break;
}
}
if (f or iv){
l = md1+1;
iv = false;
} else {
r = md1;
iv = false;
}
}
cout << (long long)l;
}
开了int128之后只能极限过前八个点(剩下全TLE)。
关int128多过了4个点,但同时出了一个WA,剩下全是多几十-一百多毫秒的TLE
这种应该怎么调,求各位大佬给个思路