社区讨论

玄关求卡常qwq

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

讨论操作

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

当前回复
4 条
当前快照
1 份
快照标识符
@mhizy4co
此快照首次捕获于
2025/11/03 18:27
4 个月前
此快照最后确认于
2025/11/03 18:27
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[100007],b[100007],c[100007],f[100007],flag[100007],d,m;
pair<int,int> p[100007];
vector<int> vec[100007];
inline int read(){
    int 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*10+ch-'0',ch=getchar();
    return x*f;
}

void pre(int u,int fa){
	f[u]=fa;
	for(register int i=0;i<vec[u].size();i++){
		int v=vec[u][i];
		if(v==fa) continue;
		pre(v,u);
	}
}
__int128 sol(int id,int l,int r){
	if(c[id]>=0) return (__int128)(r-l+(__int128)1)*(__int128)b[id]+(l+r)*(r-l+(__int128)1)/2*(__int128)c[id];
	else{
		int d=(b[id]-1)/(-c[id]);
		if(r<=d) return (__int128)(r-l+1)*(__int128)b[id]+(__int128)(l+r)*(__int128)(r-l+1)/2*(__int128)c[id];
		else if(l<=d) return (__int128)(d-l+1)*(__int128)b[id]+(__int128)(l+d)*(__int128)(d-l+1)/2*(__int128)c[id]+(__int128)(r-d);
		else return(__int128)(r-l+1);
	}
}
void dfs(int u){
	if(flag[u]) return;
	d++;flag[u]=1;
	dfs(f[u]);
}
bool check(int mid){
	for(register int i=1;i<=n;i++) flag[i]=0;
	for(register int i=1;i<=n;i++){
		int l=0,r=mid;
		while(r-l>1){
			m=(l+r)>>1;
			if(sol(i,m,mid)>=(__int128)a[i]) l=m;
			else r=m;
		}
		if(sol(i,r,mid)>=(__int128)a[i]) p[i].first=r,p[i].second=i;
		else p[i].first=l,p[i].second=i;
	}
	sort(p+1,p+n+1);
	d=1;flag[1]=1;
	for(register int i=1;i<=n;i++){
		int id=p[i].second;
		if(id==1) continue;
		dfs(id);
		if(d>p[i].first) return false;
	}
	return true;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	n=read();
	for(register int i=1;i<=n;i++) a[i]=read(),b[i]=read(),c[i]=read();
	for(register int i=1,u,v;i<n;i++) u=read(),v=read(),vec[u].emplace_back(v),vec[v].emplace_back(u);
	pre(1,0);
	int l=0,r=1000000007,mid;
	while(r-l>1){
		mid=(l+r)>>1;
		if(check(mid)) r=mid;
		else l=mid;
	}
	if(check(l)) cout<<l;
	else cout<<r;
}
求卡常 每个点都在1.2s内qwq

回复

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

正在加载回复...