25pts求条
查看原帖
25pts求条
690243
houluyu楼主2024/9/3 12:12
#include<bits/stdc++.h>
#define int __int128
#define ll __int128 
#define pii pair<int, int> 
#define f first
#define s second 
using namespace std;

const int N = 100005, inf = 0x7fffffff;
ll a[N];
int b[N], c[N], f[N], ans, n, st[N], lim[N];//st要种树的栈 
pii t[N];//最晚种的时间和编号 
bool vis[N];//是否被种树了 
vector<vector<int> > g(N);

int read()
{
	int x = 0 ,f = 1;
	char c = getchar();
	while(c > '9' || c < '0')
	{
		if(c == '-')f = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9')
	{
		x = x * 10 + c - '0';
		c = getchar();
	}
	return x * f;
 } 
 void print(int x)
{
	if(x > 9)print(x / 10);
	putchar(x % 10 + '0');
}
void dfs(int u, int fa)
{
	f[u] = fa;
	for(int i = 0; i < g[u].size(); i ++)
	{
		int v = g[u][i];
		if(v == fa)continue;
		dfs(v, u);
	}
}


ll cal(int id, int l, int r)
{
	ll ci = c[id], ai = a[id], bi = b[id]; 
	if(ci == 0ll)return (r - l + 1) * bi;
	if(ci > 0ll)return bi * (r - l + 1) + ci * (l + r) * (r - l + 1) / 2;
	ll tmx = (1 - bi) / ci; 
	if(l > tmx)return r - l + 1;
	if(r < tmx)return (r - l + 1) * bi + ci * ( r - l + 1) * (r + l) / 2;
	return (tmx - l + 1) * bi + ci * (tmx - l + 1) * (l + tmx) / 2 + r - tmx;
}

bool check(int x)
{
//	memset(vis, 0, sizeof vis);//重新标成没种树 
//	vis[0] = 1;
	memset(t, 0, sizeof t);
//	memset(st, 0, sizeof st);
	for(int i = 1; i <= n; i ++)
	{
		vis[i] = 0;
		if(cal(i, 1, x) < a[i])return 0; 
//		t[i].f = -inf;
		t[i].s = i;
		int L = 1, R = n, m, b = -1;//二分最晚第几个种   也就是不考虑父亲的情况下最晚什么时候种 
		while(L <= R)//显然具有单调性 种的越早不会比晚劣 
		{
			m = (L + R) / 2;
			if(cal(i, m, x) >= a[i])
			{
				b = m;
				L = m + 1;
			}
			else R = m - 1;
		 } 
		 lim[i] = b;
		 t[i].f = b;
//		 cout << i << ' ' << t[i].f << endl;
//		 if(t[i].f == -inf)return 0;
	}
	sort(t + 1, t + 1 + n);//对最晚种的时间排序 最晚种越早越先 
	for(int i= 1; i <= n;i  ++)
	{
//		cout << i << ' ' << t[i].f << ' ' << t[i].s << ' '<< f[t[i].s] << endl;
//		cout << vis[i] << endl;
	}
//	cout << vis[0] << endl;
	//注意第一天只能在1号地种树 
	int tim = 0;
	for(int i = 1; i <= n; i ++)
	{
		int id = t[i].s, tp = 0;
		while(!vis[id])st[++ tp] = id, vis[id] = 1, id = f[id];
		while(tp)
		{
			if(++ tim > lim[st[tp --]])
			{
				return 0; 
			}
		}
	}
	return 1;
}



signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	n = read(); 
//	cin >> n;
	for(int i = 1; i <= n; i ++)
	{
		a[i] = read();
		b[i] = read();
		c[i] = read();
	 } 
	for(int i = 1; i < n; i ++)
	{
		int u, v;
		u = read();
		v = read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs(1, 0);
	vis[0] = 1;
	int l = 0, r = 1000000000, mid;
//	cout << check(5) << endl;
//	return 0;
	while(l <= r)
	{
//		cout << 1 << endl;
		mid = (l + r) / 2;
		if(check(mid))//什么时候完成任务 
		{
//			cout << "ok" << mid << ' ' << check(mid) << endl << endl;
			ans = mid;
			r = mid - 1;
		}
		else l = mid + 1;
	}
	print(ans);
//	cout << ans << endl;	
	return 0;
 } 
2024/9/3 12:12
加载中...