社区讨论

wa 30pts 贪心求助

P9755[CSP-S 2023] 种树参与者 2已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@m1u96uc4
此快照首次捕获于
2024/10/04 12:56
去年
此快照最后确认于
2025/11/04 18:07
4 个月前
查看原帖
rt二分,每次优先种下最晚种植时间最早的树并标记路径时间,
CPP
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define int long long
using namespace std;
const int maxn=100005;
long long n,mid,tim[maxn],cnt;
struct tr
{
	int s,t;//s为序号,t为最晚种植时间 
}T[maxn];
bool cmd(tr x,tr y)
{
	return x.t<y.t;
}
long long a[maxn],b[maxn],c[maxn];
vector<int> g0[maxn],g[maxn];
bool vis[maxn];
long long solve(long long x,long long y,long long z)
{
	if(z>=0)
	{
		int l=0,r=mid;
		while(l<r)
		{
			int mi=(l+r+1)/2;
			if((mid-mi+1)*y+(mid-mi+1)*(mi+mid)*z/2>=x)
			l=mi;
			else r=mi-1;
			if(mi<=0)return -1;
		}
		return l;
	}
		int l=0,r=mid;
		int maxi=(y-1)/(-z);
		while(l<r)
		{
			int sum=0;
			int mi=(l+r+1)/2;
			if(mid<maxi)
			{
				sum=y*(mid-mi+1)+(mid-mi+1)*(mi+mid)*z/2;
			}
			else if(mi>maxi)
			{
				sum=mid-mi+1;
			}
			else{
				sum=mid-maxi+y*(maxi-mi+1)+(maxi-mi+1)*(mi+maxi)*z/2; 
			}
			//cout<<"mi:"<<mi<<' '<<"sum:"<<sum<<endl;
			if(sum>=x)
			l=mi;
			else r=mi-1;
			if(mi<=0)return -1;
		}
		return l;
	
}
void dfs(int st)
{
	for(int i=0;i<g[st].size();i++)
	{
		int to=g[st][i];
		if(!tim[to])
		{
			dfs(to);
		}
	}
	tim[st]=++cnt;
}
bool check()
{
	for(int i=1;i<=n;i++)
	{
		tim[i]=0;
		T[i].s=i;
		T[i].t=solve(a[i],b[i],c[i]);
		if(T[i].t<0)return false;
	}
	sort(T+1,T+n+1,cmd);
	cnt=0;
	for(int i=1;i<=n;i++)
	if(!tim[T[i].s])dfs(T[i].s);
	/*for(int i=1;i<=n;i++)
	{
		cout<<T[i].s<<' '<<T[i].t<<' ';
	}
	cout<<endl;*/
	for(int i=1;i<=n;i++)
	{
		if(tim[T[i].s]>T[i].t)return false;
	}
	return true;
}
void dfs0(int st)
{
	vis[st]=true;
	int to;
	for(int i=0;i<g0[st].size();i++)
	{
		to=g0[st][i];
		if(!vis[to])
		{
			g[to].push_back(st);
			dfs0(to);
		}
	}
}
signed main()
{
	mid=5;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);
	}
	for(int i=1;i<=n-1;i++)
	{
		int u,v;
		scanf("%lld%lld",&u,&v);
		g0[u].push_back(v);
		g0[v].push_back(u);
	}
	dfs0(1);
	int l=n,r=1073741823;
	while(l<r)
	{
		mid=(l+r)/2;
		if(check())r=mid;
		else l=mid+1;
	}
	cout<<l;
	return 0;
}

回复

4 条回复,欢迎继续交流。

正在加载回复...