#include <bits/stdc++.h>
#define int __int128
using namespace std;
const int N = 1e5 + 5;
int n, x, y, a[N], b[N], c[N], t[N], s[N], father[N], ans, cnt;
bool flag;
bool vis[N];
struct node{
int a, b, c;
}g[N];
struct Node{
int x, id;
}f[N];
vector<int> G[N];
inline __int128 read() {
__int128 x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') {
f = -1;
ch = getchar();
}
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
void write(__int128 x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) {
write(x / 10);
}
putchar(x % 10 + '0');
return ;
}
bool cmp (Node x, Node y){
return x.x < y.x;
}
void init(){
for (int i = 1; i <= n; ++i){
a[i] = g[i].a;
b[i] = g[i].b;
c[i] = g[i].c;
vis[i] = s[i] = 0;
}
return ;
}
void dfs (int x, int fa){
father[x] = fa;
for (int i = 0; i < G[x].size(); ++i){
if (G[x][i] == fa) continue;
dfs(G[x][i], x);
}
}
void jump_to (int x, int dep){
if (flag == 1) return ;
if (vis[x] == 1){
cnt = dep;
flag = 1;
return ;
}
vis[x] = 1;
jump_to(father[x], dep + 1);
}
bool check (int x){
init();
for (int i = 1; i <= n; ++i){
if (c[i] > 0){
int lt = 1, rt = x, pos = -1;
while (lt <= rt){
int mid = lt + rt >> 1;
if ((b[i] + mid * c[i] + b[i] + x * c[i]) * (x - mid + 1) >= 2 * a[i]){
pos = mid;
lt = mid + 1;
}else rt = mid - 1;
}
if (pos == -1) return 0;
s[i] = pos;
}else if (c[i] == 0){
if (a[i] % b[i] == 0) s[i] = x - a[i] / b[i] + 1;
else s[i] = x - a[i] / b[i];
if (s[i] <= 0) return 0;
}else if (c[i] < 0){
if (x - t[i] >= a[i]){
s[i] = x - a[i] + 1;
continue;
}
a[i] -= max((int)(0), x - t[i]);
int lt = 1, rt = min(t[i], x), pos = -1;
while (lt <= rt){
int mid = lt + rt >> 1;
if ((b[i] + mid * c[i] + b[i] + min(t[i], x) * c[i]) * (min(t[i], x) - mid + 1) >= 2 * a[i]){
pos = mid;
lt = mid + 1;
}else rt = mid - 1;
}
if (pos == -1) return 0;
s[i] = pos;
}
}
for (int i = 1; i <= n; ++i){
f[i].x = s[i];
f[i].id = i;
}
sort(f + 1, f + n + 1, cmp);
int sum = 1;
vis[1] = 1;
for (int i = 1; i <= n; ++i){
if (vis[f[i].id] == 1) continue;
flag = 0;
cnt = 0;
jump_to(f[i].id, 0);
sum += cnt;
if (sum > x || sum > f[i].x) return 0;
}
return 1;
}
signed main (){
// freopen("tree3.in", "r", stdin);
// freopen("tree3.out", "w", stdout);
n = read();
for (int i = 1; i <= n; ++i){
a[i] = read();
b[i] = read();
c[i] = read();
g[i].a = a[i];
g[i].b = b[i];
g[i].c = c[i];
}
for (int i = 1; i < n; ++i){
x = read();
y = read();
G[x].push_back(y);
G[y].push_back(x);
}
dfs(1, 0);
for (int i = 1; i <= n; ++i){
if (c[i] < 0) t[i] = (b[i] - 1) / (-c[i]);
}
int l = 1, r = 1e9;
while (l <= r){
int mid = l + r >> 1;
if (check(mid)){
ans = mid;
r = mid - 1;
}else l = mid + 1;
}
write(ans);
return 0;
}
注意主函数中二分的 r,写成 1018 时 35,改成 109 就过了,不知道是为什么,求助。