CF1059E Split the Tree(倍增)
题意翻译
现有n个点组成一棵以1为根的有根树,第i个点的点权为wi,需将其分成若干条垂直路径使得每一个点当且仅当被一条垂直路径覆盖,同时,每条垂直路径长度不能超过L,点权和不能超过S,求最少需要几条垂直路径才能满足要求。特别地,无解输出-1。
一条垂直路径是一条包含v1, v2...vk的路径,使得vi(i>=2)是vi-1的父亲。
题解
话说莫不是树上的题目全都可以用倍增艹过去……
首先,这个东西是可以贪心的,我们每一次一定是选取子树里能向上拓展最多的点与自己连成一条链
然后每一个节点最多能向上拓展多少可以用倍增预处理出来
然后直接在dfs的时候判断即可
一开始也想到要贪心了……然而最后倍增那一步没想到233
//minamoto
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=;
int head[N],Next[N],ver[N],tot;
inline void add(int u,int v){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
}
int pa[N][],top[N],son[N],dep[N],ans,n,L;ll sum[N],w[N],S;
inline void init(int u){
for(int i=;i<=;++i)
pa[u][i]=pa[pa[u][i-]][i-];
int dis=L,tmp=u;
for(int i=;i>=;--i){
int fa=pa[tmp][i];
if(!fa||(<<i)>=dis) continue;
if(sum[u]-sum[fa]+w[fa]>S) continue;
dis-=(<<i),top[u]=fa,tmp=fa;
}
}
void dfs1(int u,int fa){
sum[u]=sum[fa]+w[u],top[u]=u,dep[u]=dep[fa]+,init(u);
for(int i=head[u];i;i=Next[i])
dfs1(ver[i],u);
}
void dfs2(int u){
int mx=-;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];dfs2(v);
if(son[v]==v) continue;
if(mx==-||dep[mx]>dep[son[v]]) mx=son[v];
}
if(mx==-) ++ans,mx=top[u];
son[u]=mx;
}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d%d%lld",&n,&L,&S);
for(int i=;i<=n;++i){
scanf("%lld",&w[i]);
if(w[i]>S) return puts("-1"),;
}
for(int i=,f;i<=n;++i)
scanf("%d",&f),add(f,i),pa[i][]=f;
dfs1(,),dfs2();
printf("%d\n",ans);
return ;
}
CF1059E Split the Tree(倍增)的更多相关文章
- [CF1059E]Split the Tree[贪心+树上倍增]
题意 给定 \(n\) 个节点的树,点有点权 \(w\) ,划分成多条儿子到祖先的链,要求每条链点数不超过 \(L\) ,和不超过 \(S\),求最少划分成几条链. \(n\leq 10^5\) . ...
- [CodeForces1059E] Split the Tree
树形DP. 用倍增处理出来每个点往上能延伸出去的最远路径,nlogn 对于每个节点,如果它能被后代使用过的点覆盖,就直接覆盖,这个点就不使用,否则就ans++,让传的Max改成dp[x] #inclu ...
- [Split The Tree][dfs序+树状数组求区间数的种数]
Split The Tree 时间限制: 1 Sec 内存限制: 128 MB提交: 46 解决: 11[提交] [状态] [讨论版] [命题人:admin] 题目描述 You are given ...
- Split The Tree
Split The Tree 时间限制: 1 Sec 内存限制: 128 MB 题目描述 You are given a tree with n vertices, numbered from 1 ...
- HDU6504 Problem E. Split The Tree【dsu on tree】
Problem E. Split The Tree Problem Description You are given a tree with n vertices, numbered from 1 ...
- Codeforces Round #514 (Div. 2) E. Split the Tree(倍增+贪心)
https://codeforces.com/contest/1059/problem/E 题意 给出一棵树,每个点都有一个权值,要求你找出最少条链,保证每个点都属于一条链,而且每条链不超过L个点 和 ...
- 2018 ICPC青岛网络赛 B. Red Black Tree(倍增lca好题)
BaoBao has just found a rooted tree with n vertices and (n-1) weighted edges in his backyard. Among ...
- CF 208E. Blood Cousins [dsu on tree 倍增]
题意:给出一个森林,求和一个点有相同k级祖先的点有多少 倍增求父亲然后和上题一样还不用哈希了... #include <iostream> #include <cstdio> ...
- Codeforces 1140G Double Tree 倍增 + dp
刚开始, 我以为两个点肯定是通过树上最短路径过去的, 无非是在两棵树之间来回切换, 这个可以用倍增 + dp 去维护它. 但是后来又发现, 它可以不通过树上最短路径过去, 我们考虑这样一种情况, 起点 ...
随机推荐
- 【转载】细聊分布式ID生成方法
一.需求缘起 几乎所有的业务系统,都有生成一个记录标识的需求,例如: (1)消息标识:message-id (2)订单标识:order-id (3)帖子标识:tiezi-id 这个记录标识往往就是数据 ...
- bzoj1601【Usaco2008 Oct】灌水
1601: [Usaco2008 Oct]灌水 Time Limit: 5 Sec Memory Limit: 162 MB Submit: 1589 Solved: 1035 [Submit][ ...
- IOS7 开发注意事项
1,修改状态栏的样式和隐藏. 首先,需要在Info.plist配置文件中,增加键:UIViewControllerBasedStatusBarAppearance,并设置为YES: 然后,在UIVie ...
- Vs2012在Linux开发中的应用(6):改写Makefile项目的Build过程
MSBUILD的编译过程实际上是依据一系列的targets文件定义的.当我们在IDE运行生成.批生成.清理命令的时候.VS会查找这些命令相应的Task并运行它,以下我们逐个分析这个过程. 当运行生成操 ...
- iOS优秀博文合集
一.优化篇 Xcode7中你一定要知道的炸裂调试神技 iOS使用Instrument-Time Profiler工具分析和优化性能问题 dSYM 文件分析工具 二.功能篇 3分钟实现iOS语言本地化/ ...
- 登录日志的访问日志的 统计 MapReduce
登录日志的访问日志的 统计 MapReduce <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-commo ...
- virtualbox创建centos7虚拟机
安装Virtualbox 下载安装: 直接到官网上下载,https://www.virtualbox.org/wiki/Downloads 然后一键傻瓜式的安装即可. 设置默认虚拟电脑位置: 管理=& ...
- 自己写的canvas 手写画板
<!DOCTYPE html> <html> <head> <title>canvas</title> <meta charset=& ...
- HDU 6108 小C的倍数问题 【数学】 (2017"百度之星"程序设计大赛 - 初赛(A))
小C的倍数问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- linux杀死进程
http://blog.csdn.net/andy572633/article/details/7211546 ps -ef | grep firefox kill -s 9 1827