P9755 [CSP-S 2023] 种树 题解
首先考虑如何求出第
inline lll calc(int i,int x){
if(c[i]>=0){
return (lll)b[i]*x+(lll)c[i]*x*(x+1)/2;
}else{
int d=(b[i]-1)/(-c[i]);
if(x<=d) return (lll)b[i]*x+(lll)c[i]*x*(x+1)/2;
else return (lll)b[i]*d+(lll)c[i]*d*(d+1)/2+(x-d);
}
}
inline lll calc(int i,int l,int r){
return calc(i,r)-calc(i,l-1);
}
注:要开 __int128。
考虑二分完成时间
接下来考虑贪心,按
时间复杂度
代码:
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#define gt getchar
#define pt putchar
#define fst first
#define scd second
#define SZ(s) ((int)s.size())
typedef long long ll;
typedef unsigned long long ull;
typedef __int128 lll;
typedef unsigned int uint;
const int N=1e5+5;
using namespace std;
using namespace __gnu_pbds;
typedef pair<int,int> pii;
inline bool __(char ch){return ch>=48&&ch<=57;}
template<class T> inline void read(T &x){
x=0;bool sgn=0;char ch=gt();
while(!__(ch)&&ch!=EOF) sgn|=(ch=='-'),ch=gt();
while(__(ch)) x=(x<<1)+(x<<3)+(ch&15),ch=gt();
if(sgn) x=-x;
}
template<class T,class ...T1> inline void read(T &x,T1 &...x1){
read(x);
read(x1...);
}
template<class T> inline void print(T x){
static char stk[70];short top=0;
if(x<0) pt('-');
do{stk[++top]=x>=0?(x%10+48):(-(x%10)+48),x/=10;}while(x);
while(top) pt(stk[top--]);
}
template<class T> inline void printsp(T x){
print(x);
putchar(' ');
}
template<class T> inline void println(T x){
print(x);
putchar('\n');
}
int n;
struct Edge{
int to,nxt;
}e[N<<1];
int head[N],cnt;
inline void add_edge(int f,int t){
e[++cnt].to=t;
e[cnt].nxt=head[f];
head[f]=cnt;
}
inline void add_double(int f,int t){
add_edge(f,t);
add_edge(t,f);
}
ll a[N];
int b[N],c[N];
inline lll calc(int i,int x){
if(c[i]>=0){
return (lll)b[i]*x+(lll)c[i]*x*(x+1)/2;
}else{
int d=(b[i]-1)/(-c[i]);
if(x<=d) return (lll)b[i]*x+(lll)c[i]*x*(x+1)/2;
else return (lll)b[i]*d+(lll)c[i]*d*(d+1)/2+(x-d);
}
}
inline lll calc(int i,int l,int r){
return calc(i,r)-calc(i,l-1);
}
int fa[N],p[N],lim[N];
bool vis[N];
void dfs(int u,int fa){
::fa[u]=fa;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v!=fa) dfs(v,u);
}
}
inline bool check(int ti){
for(int i=1;i<=n;++i){
if(calc(i,ti)<a[i]) return 0;
int l=0,r=1e9;
auto chk=[&](int x){
return calc(i,x,ti)>=a[i];
};
while(l<r){
int mid=(l+r+1)>>1;
if(chk(mid)) l=mid;
else r=mid-1;
}
lim[i]=l,vis[i]=0,p[i]=i;
}
sort(p+1,p+n+1,[](int x,int y){
return lim[x]<lim[y];
});
int now=0;
for(int i=1;i<=n;++i){
int u=p[i];
if(vis[u]) continue;
int v=u;
while(!vis[v]&&v){
vis[v]=1;
now++;
v=fa[v];
}
if(now>lim[u]) return 0;
}
return 1;
}
signed main(){
read(n);
for(int i=1;i<=n;++i) read(a[i],b[i],c[i]);
for(int u,v,i=1;i<n;++i){
read(u,v);
add_double(u,v);
}
dfs(1,0);
int l=0,r=1e9;
while(l<r){
int mid=l+((r-l)>>1);
if(check(mid)) r=mid;
else l=mid+1;
}
println(l);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】