80 pts 求条
查看原帖
80 pts 求条
416975
sbno333楼主2024/10/24 22:18

函数分工很清晰。

#include<bits/stdc++.h>
using namespace std;
#define int long long
int a[100009];
int b[100009];
int c[100009];
struct st{
	int v,ne;
}sd[200009];
int h[100009];
int inn;
int n;
void add(int u,int v){
	sd[++inn].v=v;
	sd[inn].ne=h[u];
	h[u]=inn;
}
int fa[100009];
bool vis[100009];
pair<int,int> g[100009];
inline __int128 mm(int t,int r){//计算第 t 棵树如果第一天就种下,r 天长多高
	if(r<=0){
		return 0;
	}
	int x;
	if(c[t]<0)
	x=ceil((1-b[t])*1.0/c[t]);
	else{
		x=1e16;
	}
	x=max(x,1ll);
	__int128 ans;
	ans=0;
	if(x<=r){
		ans+=r-x+1;
		r=x-1;
	}
	ans+=(__int128)r*b[t];
	ans+=(__int128)r*(__int128)(r+1)/2*(__int128)c[t];
	return ans;//死亡不等式计算
}
inline int fd(int t,int y){
	int l,r;
	l=0,r=y;
	while(l<r){
		int mid;
		mid=l+r+1;
		mid>>=1;
		if((__int128)(mm(t,y)-mm(t,mid-1))>=(__int128)a[t]){//区间长高是否达到要求
			l=mid;
		}else{
			r=mid-1;
		}
	}
	return r;
}
inline void dfs(int t,int fat){
	fa[t]=fat;
	for(int i=h[t];i;i=sd[i].ne){
		if(sd[i].v!=fat){
			dfs(sd[i].v,t);
		}
	}
}
inline void input(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i]>>b[i]>>c[i];
	}
	for(int i=1;i<n;i++){
		int x,y;
		cin>>x>>y;
		add(x,y);
		add(y,x);
	}
	dfs(1,0);
}
inline bool check(int x){
	
	for(int i=1;i<=n;i++){
		vis[i]=0;
		g[i].second=i;
		g[i].first=fd(i,x);
		if(g[i].first<=0){
		    return 0;
		}
	}
	sort(g+1,g+1+n);
	int dy;
	dy=0;
	for(int i=1;i<=n;i++){
		int t;
		t=g[i].second;
		while(!vis[t]&&t){
			vis[t]=1;
			dy++;
			t=fa[t];
		}
		if(dy>g[i].first){
			return 0;
		}
	}
	return 1;
}
inline int reply(){
	int l,r;
	l=1,r=(1ll<<25);
	while(l<r){
		int mid;
		mid=l+r;
		mid>>=1;
		if(check(mid)){
			r=mid;
		}else{
			l=mid+1;
		}
	}
	return l;
}
signed main(){
	std::ios::sync_with_stdio(0);
	input();
	cout<<reply();
	return 0;
}
2024/10/24 22:18
加载中...