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 去维护它. 但是后来又发现, 它可以不通过树上最短路径过去, 我们考虑这样一种情况, 起点 ...
随机推荐
- C语言-计数排序
计数排序的基本思想是:统计一个数序列中小于某个元素a的个数为n,则直接把该元素a放到第n+1个位置上.当然当过有几个元素相同时要做适当的调整,因为不能把所有的元素放到同一个位置上.计数排序假设输入的元 ...
- C#3.0之神奇的Lambda表达式和Lambda语句
“Lambda 表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型.所有 Lambda 表达式都使用 Lambda 运算符 =>,该运算符读为“goes to” ...
- UIAutomation使用測试入门
自己主动化測试的优点: 1.自己主动化能够自己主动測试,不须要人的干预.同一时候还能够不断地反复某一个动作. 2.自己主动化測试在添加了新的功能之后.还能够回归到原理的功能,使其原来的功能不会受到影响 ...
- 浅谈xss原理
近日,论坛上面XSS满天飞,各处都能够见到XSS的痕迹,前段时间论坛上面也出现了XSS的迹象.然后我等小菜不是太懂啊,怎么办?没办法仅仅有求助度娘跟谷歌这对情侣了. 能够说小菜也算懂了一些.不敢藏私, ...
- Android学习笔记(十)——使用意图链接活动
使用意图链接活动 1.新建一个名为"UsingIntent"的项目,右击src目录下的包名,选择New-->Class选项.并将新的类文件名称命名为"SecondA ...
- Linux fcntl函数详解
功能描述:根据文件描述词来操作文件的特性. 文件控制函数 fcntl -- file control 头文件: #include <unistd.h> #include ...
- LeetCode——Binary Tree Level Order Traversal
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, ...
- 从.Net版本演变看String和StringBuilder性能之争
在C#中string关键字的映射实际上指向.NET基类System.String.System.String是一个功能非常强大且用途非常广泛的基类,所以我们在用C#string的时候实际就是在用.NE ...
- 使用Axis2开发WebService
一.准备 1.下载Axis2.eclipse插件 axis2-1.6.2-war.zip: http://mirror.bjtu.edu.cn/apache//axis/axis2/java/core ...
- Jquery根据name取得所有选中的Checkbox值
var spCodesTemp = ""; $('input:checkbox[name=supNO]:checked').each(function (i) ...