悬关求调
查看原帖
悬关求调
839893
Luka__Modric楼主2024/7/2 22:24

感觉已经跟第一篇题解差不多了,但样例还过不了

#include<bits/stdc++.h>
using namespace std;
#define int __int128
inline int read(){
   int X=0,w=0; char ch=0;
   while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
   while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
   return w?-X:X;
}
inline void print(int x){    
   if(x<0){putchar('-');x=-x;}
   if(x>9) print(x/10);
   putchar(x%10+'0');
}
int ans=1e9+10,n,b[100010],c[100010],fa[100010],st[100010],h[100010],e[200010],ne[200010],id,vis[100010],a[100010];
struct node{
	int p,t;
}w[100010];
bool cmp(node x,node y){
	return x.t<y.t;
}
void add(int x,int y){
	e[id]=y,ne[id]=h[x];
	h[x]=id++;
}
void dfs(int x,int f){
	fa[x]=f;
	for(int i=h[x];~i;i=ne[i])
		if(e[i]!=f)
			dfs(e[i],x);
}
int calc(int bian,int l,int r){
	if(c[bian]>=0)
		return (r-l+1)*b[bian]+(r-l+1)*(l+r)/2*c[bian];
	int t=(1-b[bian])/c[bian];
	if(t<l)
		return r-l+1;
	if(t>r)
		return (r-l+1)*b[bian]+(r-l+1)*(l+r)/2*c[bian];
	return (t-l+1)*b[bian]+(t-l+1)*(l+t)/2*c[bian]+r-t;
}
bool check(int x){
	for(int i=1;i<=n;i++){
		if(calc(i,1,x)<a[i])
			return false;
		int l=1,r=n;
		while(l<r){
			int mid=(l+r+1)/2;
			if(calc(i,mid,x)>=a[i])
				l=mid;
			else
				r=mid-1;
		}
		w[i].p=i,w[i].t=l,vis[i]=0;
	}
	sort(w+1,w+n+1,cmp);
	int awa=0;
	for(int i=1;i<=n;i++){
		int tmp=w[i].p,s=0;
		while(!vis[tmp]){
			s++;
			st[s]=tmp;
			vis[tmp]=1;
			tmp=fa[tmp];
		}
		for(int j=s;j>=1;j--){
			awa++;
			if(w[st[j]].t<awa)
				return false;
		}
	}
	return true;
}
signed main(){
	memset(h,-1,sizeof h);
	n=read();
	for(int i=1;i<=n;i++)
		a[i]=read(),b[i]=read(),c[i]=read();
	for(int i=1;i<n;i++){
		int x,y;
		x=read(),y=read();
		add(x,y),add(y,x);
	}
	dfs(1,0);
	vis[0]=1;
	int l=n,r=1e9;
	while(l<r){
		int mid=(l+r)/2;
		if(check(mid))
			r=mid;
		else
			l=mid+1;
	}
	print(l);
	return 0;
}
2024/7/2 22:24
加载中...