#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
const int max_answer=1e9+1;
struct earth
{
typedef __int128 number_space;
long long a,b,c;
earth(long long s=0,long long d=0,long long f=0)
{
a=s;
b=d;
c=f;
}
bool calc(number_space l,number_space r)
{
//return true;
number_space a1=a,b1=b,c1=c,i=0;
//b>=1
if(c1>=0)
{
goto growing_quickly;
}
//sigma(i=l~r)b+i*c
//=sigma(i=l~r)b+sigma(i=l~r)i*c
//=b*(r-l+1)+c*sigma(i=l~r)i
//=b*(r-l+1)+c*(l+r)8(r-l+1)/2 (首项+末项)*项数/2
else
{
i=(1-b1)/c1;
//b+i*c>=1 最大 i
if(i<l)
goto growing_slowly;
else if(i>r)
goto growing_quickly;
else
goto growing_in_middle;
}
return false;
growing_slowly:
return r-l+1 >= a1;
growing_quickly:
return (b1*(r-l+1)+(r-l+1)/2*c1*(l+r)) >= a1;
growing_in_middle:
return (b1*(i-l+1)+(i-l+1)/2*c1*(l+i))/*grow quickly*/ + (r-i)/*grow slowly*/ >= a1;
}//l~r 能成不
}dikuai[maxn+1];
int fa[maxn+1],t[maxn+1],p[maxn+1];
stack<int>s;
bool vis[maxn+1];
vector<int>bian[maxn+1];
int n;
inline void dfs(int f,int u)
{
fa[u]=f;
for(auto ed:bian[u])
if(ed != f)
dfs(u,ed);
return;
}
bool check(int x)
{
for(int i=1,l2,r2;i<=n;i++)
{
if(!dikuai[i].calc(1,x))
return false;//这一段时间里不行
l2=1,r2=n;
while(l2<r2)
{
auto mid=(l2+r2+1)>>1;
if(dikuai[i].calc(mid,x))
l2=mid;
else
r2=mid-1;
}
p[i]=i;
t[i]=l2;//最晚时刻
vis[i]=false;//重置
}
sort(p+1,p+n+1,[](int A,int B)->bool{return t[A]<t[B];});
for(int i=1,now,now_time=0;i<=n;i++)
{
now=p[i];//现在指向那个节点
while(!vis[now])
{
s.push(now);
vis[now]=true;
now=fa[now];
}
while(!s.empty())
{
if(t[s.top()]<++now_time)
{
s.pop();
return false;//时间超了
}
else
{
s.pop();
}
}
}
return true;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld%lld%lld",&dikuai[i].a,&dikuai[i].b,&dikuai[i].c);
}
for(int q=1,u,v;q<n;q++)
{
scanf("%d%d",&u,&v);
bian[u].push_back(v);
bian[v].push_back(u);
}
vis[0]=true;
dfs(0,1);
int wer=max_answer,r=max_answer,l=n;//至少要 n 天把树全部种上
while(l<r)
{
int mid=(l+r)>>1;
if(check(mid))
{
//wer=min(wer,mid);
r=mid;
}
else
l=mid+1;
}//[l,r]二分时间
printf("%d",l);
return 0;
}
RE
将 sort(p+1,p+n+1,[](int A,int B)->bool{return t[A]<t[B];}); 改为 sort(p+1,p+n+1,[](int A,int B)->bool{return t[A]<t[B];}); 不 RE 了。
求神犇答疑解惑