CSP-S T4 求调
  • 板块学术版
  • 楼主zhangjunzhe
  • 当前回复5
  • 已保存回复5
  • 发布时间2023/10/22 11:58
  • 上次更新2023/11/2 11:57:04
查看原帖
CSP-S T4 求调
579866
zhangjunzhe楼主2023/10/22 11:58

csp s4 求调

我是先二分答案

再预处理出每棵树最晚什么时候种(d数组)

再求每个点的子树的最小值(w数组)

最后优先队列+深搜

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll getin(){
	ll ans=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-') f=-1; 
		c=getchar();
	}
	while(c>='0'&&c<='9') ans=(ans<<1)+(ans<<3)+(c-'0'),c=getchar();
	return ans*f;
};
const int N=100010;
const ll inf=1000000000000000010;
struct node{
	ll to,next;
}e[N<<1];
ll cnt,h[N];
void add(ll u,ll v){
	++cnt;
	e[cnt].next=h[u];
	e[cnt].to=v;
	h[u]=cnt;
}
ll n;
ll a[N],b[N],c[N],d[N],w[N];
bool vis[N];
priority_queue<pair<ll,ll> > q;
ll js(ll x,ll y,ll i){
	if(c[i]!=0){if((a[i]-(y-x+1)*b[i])/c[i]<=(x+y)*(y-x+1)/2) return inf;}
	return (x+y)*(y-x+1)/2*c[i]+(y-x+1)*b[i];
}
void dfs1(ll u){
	w[u]=d[u];
	for(ll i=h[u];i;i=e[i].next){
		ll v=e[i].to;
		if(vis[v])continue;
		vis[v]=1;
		dfs1(v);
		w[u]=min(w[u],w[v]);
	}
}
bool dfs(ll u,ll day){
	for(ll i=h[u];i;i=e[i].next){
		ll v=e[i].to;
		if(vis[v])continue;
		vis[v]=1;
		q.push(make_pair(-w[v],v));
	}
	if(!q.empty()){
		ll x=q.top().second;
		ll dd=d[x];
		q.pop();
		if(dd<=day)return false;
		return dfs(x,day+1);
	}
	return true;
}
bool check(ll x){
	for(ll i=1;i<=n;i++){
		if(c[i]>=0){
			ll l=0,r=x+1;
			while(l+1<r){
				ll mid=(l+r)>>1;
				if(js(mid,x,i)>=a[i]) l=mid;
				else r=mid;
			}
			if(l==0)return false;
			d[i]=l;
		}
		else {
			ll m=b[i]/(-c[i]);
			if(b[i]%(-c[i])==0)m--;
			if(m>x){
				ll l=0,r=x+1;
				while(l+1<r){
					ll mid=(l+r)>>1;
					if(js(mid,x,i)>=a[i]) l=mid;
					else r=mid;
				}
				if(l==0)return false;
				d[i]=l;
			}
			else {
				if(x-m>=a[i]){
					d[i]=x-a[i]+1;
					continue;
				}
				ll l=0,r=m+1;
				while(l+1<r){
					ll mid=(l+r)>>1;
					if(js(mid,m,i)+(x-m)>=a[i]) l=mid;
					else r=mid;
				}
				if(l==0)return false;
				d[i]=l;
			}
		}
	}
	
	while(!q.empty())q.pop();
	memset(vis,0,sizeof(vis));
	memset(w,0x3f,sizeof(w));
	vis[1]=1;
	dfs1(1);
	
	memset(vis,0,sizeof(vis));
	vis[1]=1;
	return dfs(1,1);
}
int main(){
	freopen("tree.in","r",stdin);
	freopen("tree.out","w",stdout);
	cin>>n;
	for(ll i=1;i<=n;i++){
		a[i]=getin();
		b[i]=getin();
		c[i]=getin();
	}
	for(ll i=1;i<n;i++){
		ll u,v;
		u=getin();
		v=getin();
		add(u,v);add(v,u);
	}
	ll l=0,r=1000000001;
	while(l+1<r){
		ll mid=(l+r)>>1;
		if(check(mid)) r=mid;
		else l=mid;
	}
	cout<<r;
	fclose(stdin);
	fclose(stdout);
	return 0;
}
2023/10/22 11:58
加载中...