我的思路和题解差不多,就是判断可行性那里我先算出对于每一个 i 能长到 i 的最晚天数,然后 dfs 处理要满足 i 的子树时的最晚天数,对于然后记 sumi 表示最晚天数小于 i 天的点的个数,那么可行性就是对于所有的 i sumi≤i,等价于差分数组都为非负数,但是只有 1~8 的40 pts,思路有什么问题吗?
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lll __int128
#define ull unsigned ll
#define ld long double
#define db double
template<typename T>inline void read(T& x) {
x=0;int f=1;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=~f+1;ch=getchar();}
while (isdigit (ch)) {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
x*=f;
}
template <typename T,typename... Args> inline void read(T& x, Args&... args) {
read(x);
read(args...);
}
template<typename T>inline void write(T x) {
static int buf[40],top=0;
if(x<0)putchar('-'),x=~x+1;
while(x)buf[++top]=x%10,x/=10;
if(top==0)buf[++top]=0;
while (top) putchar(buf[top--]^48);
putchar(' ');
}
template <typename T,typename... Args> inline void write(T x, Args... args) {
write(x);
write(args...);
}
template<typename T>inline T Max(T a,T b){
return a>b?a:b;
}
template<typename T,typename ...Args>inline T Max(T a,T b,Args... args){
return Max(a,Max(b,args...));
}
template<typename T>inline T Min(T a,T b){
return a<b?a:b;
}
template<typename T,typename ...Args>inline T Min(T a,T b,Args... args){
return Min(a,Min(b,args...));
}
const int maxn=1e5+10;
int n,T;
vector<int>son[maxn];
ll a[maxn],b[maxn],c[maxn],ropz[maxn];
// -1 Impossible to > 1 ;-2 >1 permanently
ll calc(int i,int s,int t){
if(c[i]==0){
return (t-s+1)*1ll*(b[i]>=1?b[i]:1);
}
else if(c[i]>0){
if(ropz[i]<s){
return (t-s+1)*1ll*b[i]+(t+s)*1ll*(t-s+1)/2*c[i]*1ll;
}
else if(ropz[i]>t){
return t-s+1;
}
else {
return ropz[i]-s+(t-ropz[i]+1)*1ll*b[i]+(ropz[i]+t)*1ll*(t-ropz[i]+1)/2*c[i]*1ll;
}
}
else{
if(ropz[i]>t){
return (t-s+1)*1ll*b[i]+(t+s)*1ll*(t-s+1)/2*c[i]*1ll;
}
else if(ropz[i]<s){
return t-s+1;
}
else {
return t-ropz[i]+(ropz[i]-s+1)*1ll*b[i]+(ropz[i]+s)*1ll*(ropz[i]-s+1)/2*c[i]*1ll;;
}
}
}
int Find(int i,int E){
int l=1,r=E-1,ans=1;
while(l<=r){
int mid=l+r>>1;
if(calc(i,mid,E)>=a[i]){
ans=mid;
l=mid+1;
}
else {
r=mid-1;
}
}
return ans;
}
int st[maxn];
void dfs(int u,int fa){
sort(son[u].begin(),son[u].end(),[](int A,int B){
return st[A]>st[B];
});
for(int v:son[u]){
if(v==fa)continue;
dfs(v,u);
}
for(int i(1);i<(int)son[u].size();++i){
if(son[u][i]==fa)continue;
else if(son[u][i-1]==fa){
if(i>1){
if(st[son[u][i]]==st[son[u][i-2]]){
st[son[u][i]]--;
}
}
}
else if(st[son[u][i]]==st[son[u][i-1]]){
st[son[u][i]]--;
}
st[u]=min(st[u],st[son[u][i]]-1);
}
// write(u,st[u]);
// puts("::");
// for(int v:son[u]){
// if(v==fa)continue;
// write(v,st[v]);
// puts("");
// }
// puts("SS");
}
int C[maxn];
inline int lowbit(int x){
return x&(-x);
}
inline void change(int x,int k){
while(x<=n){
C[x]+=k;
x+=lowbit(x);
}
}
inline int query(int x){
int res=0;
while(x>0){
res+=C[x];
x-=lowbit(x);
}
return res;
}
bool check(int x){
for(int i(1);i<=n;++i){
st[i]=Find(i,x);
// write(st[i]);
C[i]=0;
}
for(int i(1);i<=n;++i){
change(i,1);
}
dfs(1,0);
for(int i(1);i<=n;++i){
// write(st[i]);
if(st[i]<=0)return 0;
if(st[i]>n)continue;
change(st[i],-1);
}
for(int i(1);i<=n;++i){
// write(query(i));
if(query(i)<0)return 0;
}
return 1;
}
int main(){
read(n);
for(int i(1);i<=n;++i){
read(a[i],b[i],c[i]);
if(c[i]==0)ropz[i]=b[i]>=1?-1:-2;
else if(c[i]>0){
ropz[i]=(ll)ceil((ld)(1-b[i]+0.0)/(ld)(c[i]+0.0));
}
else {
ropz[i]=(ll)floor((ld)(1-b[i]+0.0)/(ld)(c[i]+0.0));
}
}
for(int i(1),u,v;i<n;++i){
read(u,v);
son[u].emplace_back(v);
son[v].emplace_back(u);
}
// int w=check(5);
// write(w);
int l=1,r=1e9,ans=1e9;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid)){
r=mid-1;
ans=mid;
}
else l=mid+1;
}
write(ans);
return 0;
}