95 pts 求助
查看原帖
95 pts 求助
421265
eastcloud楼主2023/10/30 08:03

rt,第 15 个点 wa 了,跟答案就差 1,不知道思路哪里有问题

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
#define N 500005
#define ll long long
#define lll __int128
using namespace std;
vector<int> E[N];
ll read(){
	ll x=0,f=1;char ch=getchar();
	while(ch<'0' || ch>'9'){
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0' && ch<='9'){
		x=(x<<1ll)+(x<<3ll)+(ch^48);
		ch=getchar();
	}
	return x*f;
}
ll a[N],b[N],c[N],nex[N],to[N],e,head[N],f[N];
ll n,now=0,flag=0,lim[N],sta[N],cnt;
int vis[N];
struct Node{
	ll num,val;
};
bool operator <(Node x,Node y){
	return x.val>y.val;
}
priority_queue<Node> q;
void add(ll u,ll v){
	to[++e]=v;nex[e]=head[u];head[u]=e;E[u].push_back(v);
	to[++e]=u;nex[e]=head[v];head[v]=e;E[v].push_back(u);
}
bool solve(ll x){
	bool flag=true;
	if(f[x] && !vis[f[x]])flag=solve(f[x]);
	now++;
	if(now>lim[x])return false;
	vis[x]++;
	return flag;
}
void write(ll x){
	if(x/10)write(x/10);
	putchar(x%10+'0');
}
lll ask(lll A,lll B,lll C,lll ti,lll l,lll r){
	if(ti*B+(ti+1)*(ti)/2*C<A){flag=1;return 0;}
	while(l<r){
		lll mid=(l+r+1)>>1;
		if((ti-mid+1)*B+(ti+mid)*(ti-mid+1)/2*C>=A)l=mid;
		else r=mid-1;
	}
	return l;
}
bool check(ll val){
	now=0;flag=0;
	for(ll i=1;i<=n;i++)vis[i]=0;
	while(q.size())q.pop();
	for(ll i=1;i<=n;i++){
		lim[i]=0;
		ll l=1,r=min(val,n),B=b[i],C=c[i],ti=val,A=a[i];
		if(C<0){
			ll t=(1-B)/C;
			if(ti-t>=A)lim[i]=ti-A+1;
			A-=(ti-t);r=min(t,n);ti=t;
		}
		if(!lim[i])lim[i]=ask(A,B,C,ti,l,r);q.push((Node){i,lim[i]});
	}
	if(flag)return false;
	for(ll i=1;i<=n;i++){
		ll u=q.top().num;q.pop();
		if(vis[u])continue;
		if(!solve(u))return false;
	}
	return true;
}

int main(){
	//freopen("a.txt","r",stdin);
	n=read();
	for(ll i=1;i<=n;i++){a[i]=read();b[i]=read();c[i]=read();}
	for(ll i=1;i<n;i++){ll u=read(),v=read();add(u,v);}
	sta[++cnt]=1;
	while(cnt){
		int u=sta[cnt--];
		for(int i=head[u];i;i=nex[i]){
			int v=to[i];if(v==f[u])continue;
			f[v]=u;sta[++cnt]=v;
		}
	}
	ll l=n,r=1000000000;
	while(l<r){
		ll mid=(l+r)>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	write(l);
	return 0;
}
2023/10/30 08:03
加载中...