当前位置: 首页 > news >正文

P9755 [CSP-S 2023] 种树

题目描述

你是一个森林养护员,有一天,你接到了一个任务:在一片森林内的地块上种树,并养护至树木长到指定的高度。

森林的地图有 nnn 片地块,其中 111 号地块连接森林的入口。共有 n−1n-1n1 条道路连接这些地块,使得每片地块都能通过道路互相到达。最开始,每片地块上都没有树木。

你的目标是:在每片地块上均种植一棵树木,并使得 iii 号地块上的树的高度生长到不低于 aia_iai 米。

你每天可以选择一个未种树且与某个已种树的地块直接邻接即通过单条道路相连)的地块,种一棵高度为 000 米的树。如果所有地块均已种过树,则你当天不进行任何操作。特别地,第 111 天你只能在 111 号空地种树。

对每个地块而言,从该地块被种下树的当天开始,该地块上的树每天都会生长一定的高度。由于气候和土壤条件不同,在第 xxx 天,iii 号地块上的树会长高 max⁡(bi+x×ci,1)\max(b_i + x \times c_i, 1)max(bi+x×ci,1) 米。注意这里的 xxx 是从整个任务的第一天,而非种下这棵树的第一天开始计算。

你想知道:最少需要多少天能够完成你的任务?

输入格式

输入的第一行包含一个正整数 nnn,表示森林的地块数量。

接下来 nnn 行:每行包含三个整数 ai,bi,cia_i, b_i, c_iai,bi,ci,分别描述一片地块,含义如题目描述中所述。

接下来 n−1n-1n1 行:每行包含两个正整数 ui,viu_i, v_iui,vi,表示一条连接地块 uiu_iuiviv_ivi 的道路。

输出格式

输出一行仅包含一个正整数,表示完成任务所需的最少天数。

输入输出样例 #1

输入 #1

4
12 1 1
2 4 -1
10 3 0
7 10 -2
1 2
1 3
3 4

输出 #1

5

说明/提示

【样例 1 解释】

111 天:在地块 111 种树,地块 111 的树木长高至 222 米。

222 天:在地块 333 种树,地块 1,31, 31,3 的树木分别长高至 5,35, 35,3 米。

333 天:在地块 444 种树,地块 1,3,41, 3, 41,3,4 的树木分别长高至 9,6,49, 6, 49,6,4 米。

444 天:在地块 222 种树,地块 1,2,3,41, 2, 3, 41,2,3,4 的树木分别长高至 14,1,9,614, 1, 9, 614,1,9,6 米。

555 天:地块 1,2,3,41, 2, 3, 41,2,3,4 的树木分别长高至 20,2,12,720, 2, 12, 720,2,12,7 米。

【样例 2】

见选手目录下的 tree/tree2.intree/tree2.ans

【样例 3】

见选手目录下的 tree/tree3.intree/tree3.ans

【样例 4】

见选手目录下的 tree/tree4.intree/tree4.ans

【数据范围】

对于所有测试数据有:1≤n≤105,1≤ai≤1018,1≤bi≤109,0≤∣ci∣≤109,1≤ui,vi≤n1 ≤ n ≤ 10^5,1 ≤ a_i ≤ 10^{18}, 1 ≤ b_i ≤ 10^9,0 ≤ |c_i| ≤ 10^9, 1 ≤ u_i, v_i ≤ n1n105,1ai1018,1bi109,0ci109,1ui,vin。保证存在方案能在 10910^9109 天内完成任务。

T4

特殊性质 A:对于所有 1≤i≤n1 ≤ i ≤ n1in,均有 ci=0c_i = 0ci=0

特殊性质 B:对于所有 1≤i<n1 ≤ i < n1i<n,均有 ui=iu_i = iui=ivi=i+1v_i = i + 1vi=i+1

特殊性质 C:与任何地块直接相连的道路均不超过 222 条;

特殊性质 D:对于所有 1≤i<n1 ≤ i < n1i<n,均有 ui=1u_i = 1ui=1

解题思路

  • 资源计算函数 fin
  • 该函数计算节点 x 在时间区间 [l, r] 内获取的资源总量。
  • 若 c[x] >= 0,资源增长为线性函数,直接计算总和。
  • 若 c[x] < 0,资源增长在某个时间点达到最大值后停止增长,需分段计算。
  • 二分搜索时间 t
  • 通过二分法确定满足所有节点资源需求的最小时间 t。初始范围为 [n, 1e9],逐步缩小范围。
  • 验证时间 t 是否可行
  • 对于每个节点,计算其在 [1, t] 内能否满足 a[i]。
  • 若满足,进一步计算满足 a[i] 的最小时间 ti[i](即最早满足需求的时间)。
  • 将所有节点按 ti[i] 排序,模拟资源分配过程,确保每个节点在其 ti[i] 前被访问。
    树的遍历与验证
  • 使用深度优先搜索(DFS)预处理父节点关系。
  • 按 ti[i] 排序后,模拟从根节点到各节点的访问顺序,确保时间约束。

代码解释

#include<bits/stdc++.h>
using namespace std;
#define ___ __int128
const int N=1e5+15;
int b[N],c[N],n,fa[N],stk[N];
long long a[N];
int tot,h[N*2],ne[N*2],to[N*2];
int id[N],ti[N];
bool yon[N];

宏与全局变量
___ 定义为 __int128,用于大数计算避免溢出。
a[i] 是节点资源需求,b[i] 和 c[i] 是资源增长函数的参数。
fa[i] 存储父节点,id 和 ti 用于排序和验证。
yon[i] 标记节点是否被访问过。

void add(int a,int b) {tot++;ne[tot]=h[a];h[a]=tot;to[tot]=b;
}

邻接表添加边
用于构建树的邻接表结构。

bool cmp(int a,int b) {return ti[a]<ti[b];
}

排序比较函数
按节点满足需求的时间 ti[i] 排序。

void dfs(int u,int f) {fa[u]=f;for(int i=h[u];i;i=ne[i]) {int j=to[i];if(j!=f)dfs(j,u);}
}
  • DFS预处理父节点
  • 从根节点开始遍历树,记录每个节点的父节点。

___ fin(int x,___ l,___ r) {if(c[x]>=0) return (r-l+1)*b[x]+(r-l+1)*(l+r)/2*c[x];___ g=(1-b[x])/c[x];if(g<l) return r-l+1;if(g>r) return (r-l+1)*b[x]+(r-l+1)*(l+r)/2*c[x];return (g-l+1)*b[x]+(g-l+1)*(l+g)/2*c[x]+r-g;
}
  • 资源计算函数
  • 根据 c[x] 的符号选择计算方式:
  • c[x] >= 0:线性增长,直接求和。
  • c[x] < 0:分段计算,先线性增长到峰值后停止。
bool check(int t) {for(int i=1;i<=n;i++) {if(fin(i,1,t)<a[i])return 0;else {int l=1,r=n;while(l<r) {int mid=(l+r+1)>>1;if(fin(i,mid,t)>=a[i])l=mid;else r=mid-1;}id[i]=i;ti[i]=l;yon[i]=0;}}sort(id+1,id+1+n,cmp);int js=0;for(int i=1;i<=n;i++) {if(yon[id[i]])continue;stack<int>s1;int x=id[i];while(!yon[x]) {yon[x]=1;s1.push(x);if(fa[x]!=0)x=fa[x];}while(!s1.empty()) {int j=s1.top();s1.pop();js++;if(ti[j]<js)return 0;}}return 1;
}

验证函数
检查每个节点在 [1, t] 内是否满足 a[i]。
对满足的节点,计算其最小满足时间 ti[i]。
按 ti[i] 排序后模拟访问顺序,确保时间约束。

int main() {ios::sync_with_stdio(false),cin.tie(0);cin>>n;int aa,bb;for(int i=1;i<=n;i++)cin>>a[i]>>b[i]>>c[i];for(int i=1;i<n;i++) {cin>>aa>>bb;add(aa,bb);add(bb,aa);}dfs(1,0);int l=n,r=1e9;while(l<r) {int mid=(l+r)>>1;if(check(mid))r=mid;elsel=mid+1;}cout<<l;return 0;
}
  • 主函数
  • 输入树结构和节点参数。
  • 预处理父节点关系。
  • 二分搜索最小时间 t。
  • 输出结果。

复杂度分析

  • 时间复杂度:二分搜索 O(log(1e9)),每次验证 O(n log n),总复杂度 O(n log n log(1e9))。
  • 空间复杂度:O(n),存储树结构和中间变量。

详细代码

#include<bits/stdc++.h>
using namespace std;
#define ___ __int128
const int N=1e5+15;
int b[N],c[N],n,fa[N],stk[N];
long long a[N];
int tot,h[N*2],ne[N*2],to[N*2];
int id[N],ti[N];
bool yon[N];
void add(int a,int b)
{tot++;ne[tot]=h[a];h[a]=tot;to[tot]=b;
}
bool cmp(int a,int b)
{return ti[a]<ti[b];
}
void dfs(int u,int f)
{fa[u]=f;for(int i=h[u];i;i=ne[i]){int j=to[i];if(j!=f)dfs(j,u);}
}
___ fin(int x,___ l,___ r)
{if(c[x]>=0) return (r-l+1)*b[x]+(r-l+1)*(l+r)/2*c[x];___ g=(1-b[x])/c[x];if(g<l) return r-l+1;if(g>r) return (r-l+1)*b[x]+(r-l+1)*(l+r)/2*c[x];return (g-l+1)*b[x]+(g-l+1)*(l+g)/2*c[x]+r-g;
}
bool check(int t)
{for(int i=1;i<=n;i++){if(fin(i,1,t)<a[i])return 0;else{int l=1,r=n;while(l<r){int mid=(l+r+1)>>1;if(fin(i,mid,t)>=a[i])l=mid;else r=mid-1;}id[i]=i;ti[i]=l;yon[i]=0;}}sort(id+1,id+1+n,cmp);int js=0;for(int i=1;i<=n;i++){if(yon[id[i]])continue;stack<int>s1;int x=id[i];while(!yon[x]){yon[x]=1;s1.push(x);if(fa[x]!=0)x=fa[x];}while(!s1.empty()){int j=s1.top();s1.pop();js++;if(ti[j]<js)return 0;}}return 1;
}
int main()
{ios::sync_with_stdio(false),cin.tie(0);cin>>n;int aa,bb;for(int i=1;i<=n;i++)cin>>a[i]>>b[i]>>c[i];for(int i=1;i<n;i++){cin>>aa>>bb;add(aa,bb);add(bb,aa);}dfs(1,0);int l=n,r=1e9;while(l<r){int mid=(l+r)>>1;if(check(mid))r=mid;elsel=mid+1;}cout<<l;return 0;
}
http://www.dtcms.com/a/273873.html

相关文章:

  • 浮点测试初探
  • Genus:设计信息结构以及导航方式(路径种类)
  • Java中的泛型继承
  • 【C语言进阶】带你由浅入深了解指针【第四期】:数组指针的应用、介绍函数指针
  • 【Spring Boot】Spring Boot 4.0 的颠覆性AI特性全景解析,结合智能编码实战案例、底层架构革新及Prompt工程手册
  • mysql的LIMIT 用法
  • 1 APP-OneNET 生成token密钥
  • Ubuntu2404修改国内镜像
  • 我的第一个开源项目|Geex:道阻且长的开源之路
  • docker的学习
  • React中Redux基础和路由介绍
  • 将手工建模模型(fbx、obj)转换为3dtiles的免费工具!
  • threejs案例开发-中国3D国旗动画
  • PostgreSQL 查询库中所有表占用磁盘大小、表大小
  • [Meetily后端框架] 多模型-Pydantic AI 代理-统一抽象 | SQLite管理
  • 共享储能电站在工业用户经济调度中的matlab仿真
  • 需求升级,创新破局!苏州金龙赋能旅游客运新生态
  • Go中使用wire进行统一依赖注入管理
  • 【JavaScript高级】构造函数、原型链与数据处理
  • 3 OneNET-调试器模拟上报数据
  • 深入理解Spring声明式事务的同步管理机制
  • C++ 面向对象 - 对象定义方法汇总
  • MySQL:分析表锁的常见问题
  • Flowable 使用遇到问题
  • Redis Sentinel哨兵集群
  • 碳中和目标下的全球产业链重构:深度解析与未来路径
  • Maui劝退:用windows直接真机调试iOS,无须和Mac配对
  • 单片机显示Unicode字符介绍
  • PDXP、UDP与HDLC协议技术解析:架构、应用与对比研究
  • SpringBoot 拦截器和过滤器的区别