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

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.xdnf.cn/news/15293.html

相关文章:

  • 【JavaScript高级】构造函数、原型链与数据处理
  • OS16.【Linux】冯依诺曼体系结构和操作系统的浅层理解
  • docker-compose安装常用中间件
  • 【unitrix】 4.21 类型级二进制数基本结构体(types.rs)
  • 1965–2022年中国大陆高分辨率分部门用水数据集,包含:灌溉用水、工业制造用水、生活用水和火电冷却
  • C语言的程序控制语句
  • VR协作海外云:跨国企业沉浸式办公解决方案
  • 决策树算法在医学影像诊断中的广泛应用
  • ch07 题解
  • 番外-linux系统运行.net framework 4.0的项目
  • [特殊字符]远程服务器配置pytorch环境
  • 设计模式笔记_结构型_代理模式
  • 基于vscode开发工具显示git提交信息的插件
  • 世界现存燃油汽车品牌起源国别梳理
  • 【实时Linux实战系列】硬实时与软实时设计模式
  • 【网络】Linux 内核优化实战 - net.netfilter.nf_conntrack_max
  • 基于开源AI智能名片链动2+1模式与S2B2C商城小程序的渠道选择策略研究
  • BPE(Byte Pair Encoding)分词算法
  • flutter鸿蒙版 环境配置
  • 在前端项目中是如何解决跨域的
  • 解决Vue页面黑底红字遮罩层报错:Unknown promise rejection reason (webpack-internal)
  • CSP-J/S 参赛选手注册报名流程
  • 智能文本抽取在合同管理实战应用
  • AIC8800M40低功耗wifi在ARM-LINUX开发板上做OTA的调试经验
  • 借助 Wisdom SSH AI 助手,轻松安装 CentOS 8 LNMP 环境
  • 2025前端面试真题以及答案-不断整理中,问题来源于牛客真题
  • CMU15445-2024fall-project1踩坑经历
  • hive/spark sql中unix_timestamp 函数的坑以及时间戳相关的转换
  • 串行数据检测器,检测到011,Y输出1,否则为0.
  • RabbitMQ 之顺序性保障