玄关
查看原帖
玄关
632311
huyangmu楼主2025/1/17 08:44

#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;
}

注意主函数中二分的 rr,写成 101810^{18}3535,改成 10910^9 就过了,不知道是为什么,求助。

2025/1/17 08:44
加载中...