90分悬关求调,马蜂良好(自认为)
查看原帖
90分悬关求调,马蜂良好(自认为)
752711
hateful_bug楼主2024/10/22 17:21
#include<bits/stdc++.h>
#define LL __int128
using namespace std;
const int N=100005;
typedef pair<int,int> pi;
pi t[N];
int n,h[N],nx[N<<1],v[N<<1],tt,l,r=1000000000,mid,f[N];
LL a[N],b[N],c[N];
bool pd[N];
void zj(int x,int y)
{
	v[++tt]=y;
	nx[tt]=h[x];
	h[x]=tt;
}
void dfs(int x,int fa)
{
	f[x]=fa;
	for(int i=h[x];i;i=nx[i])
	if(v[i]!=fa)
	dfs(v[i],x);
}
bool js(int i,LL l)
{
	LL r=mid;
	if(c[i]>=0)
	return ( (r-l+1)*b[i]+(r-l+1)*(r+l)/2*c[i] )>=a[i];
	else
	{
		int zzd=(1-b[i])/c[i];
		if(zzd<=l)
		return (r-l+1)>=a[i];
		else if(zzd>r)
		return ( (r-l+1)*b[i]+(r-l+1)*(r+l)/2*c[i] )>=a[i];
		else
		return ( (r-zzd+1)+(zzd-l)*b[i]+(zzd-l)*(zzd+l-1)/2*c[i] )>=a[i];
	}
}
bool solve()
{
	memset(pd,false,sizeof(pd));
	pd[0]=true;
	int tt=0;
	for(int i=1;i<=n;i++)
	{
		int l=0,r=mid;
		while(l<r)
		{
			int zj=(l+r+1)/2;
			if(js(i,zj))
			l=zj;
			else
			r=zj-1;
		}
		t[i].first=l;
		t[i].second=i;
	}
	sort(t+1,t+n+1);
	for(int i=1;i<=n;i++)
	{
		int x=t[i].second,y=t[i].first;
		while(!pd[x])
		{
			++tt;
			pd[x]=true;
			x=f[x];
		}
		if(tt>y)
		return false;
	}
	return true;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);
	for(int i=1;i<n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		zj(x,y);zj(y,x); 
	}
	dfs(1,0);
	while(l<r)
	{
		mid=(l+r)>>1;
		if(solve())
		r=mid;
		else
		l=mid+1;
	}
	printf("%d",l);
	return 0;
}
2024/10/22 17:21
加载中...