Codeforces-1059E:Split the Tree(貪心+倍增)
E. Split the Tree
time limit per test 2 seconds
memory limit per test 256 megabytes
inputstandard input
outputstandard output
You are given a rooted tree on n vertices, its root is the vertex number 1. The i-th vertex contains a number . Split it into the minimum possible number of vertical paths in such a way that each path contains no more than L vertices and the sum of integers on each path does not exceed S. Each vertex should belong to exactly one path.
A vertical path is a sequence of vertices where is the parent of .
Input
The first line contains three integers n, L, S — the number of vertices, the maximum number of vertices in one path and the maximum sum in one path.
The second line contains n integers — the numbers in the vertices of the tree.
The third line contains n−1 integers , where is the parent of the i-th vertex in the tree.
Output
Output one number — the minimum number of vertical paths. If it is impossible to split the tree, output −1.
Examples
input
3 1 3
1 2 3
1 1
output
3
input
3 3 6
1 2 3
1 1
output
2
input
1 1 10000
10001
output
-1
思路:對於一個以k為根結點的子樹來說,k的所有兒子都會延伸上來一條鏈,那麼現在就是從這些鏈中選一條鏈,那麼當然是選一條向上延伸最長的啦。
求出這條鏈向上延伸的最長長度就要用到倍增了。
#include<bits/stdc++.h>
using namespace std;
const int MAX=1e5+10;
const int MOD=1e9+7;
const long long INF=2e18;
typedef long long ll;
vector<int>e[MAX];
ll a[MAX];
ll sum[MAX][21];
int nex[MAX][21];
int cal(pair<int,ll>now,int k,ll L,ll S)
{
int cnt=0;
for(int i=20;i>=0;i--)
{
if(sum[k][i]+now.second>S)continue;
if((1<<i)+now.first>L)continue;
L-=1<<i;
S-=sum[k][i];
k=nex[k][i];
cnt+=1<<i;
}
return cnt;
}
ll L,S;
int ans=0;
pair<int,ll>dfs(int k,int fa)
{
nex[k][0]=fa;
for(int i=1;i<=20;i++)nex[k][i]=nex[nex[k][i-1]][i-1];
sum[k][0]=a[k];
for(int i=1;i<=20;i++)sum[k][i]=min(sum[k][i-1]+sum[nex[k][i-1]][i-1],INF);
pair<int,ll>QWQ=make_pair(0,0);
int cnt=0;
for(int i=0;i<e[k].size();i++)
{
pair<int,ll> now=dfs(e[k][i],k);
if(cal(now,k,L,S)>cnt)
{
cnt=cal(now,k,L,S);
QWQ=now;
}
}
if(QWQ.first==0&&ans!=-1)
{
if(QWQ.first+1<=L&&QWQ.second+a[k]<=S)ans++;
else ans=-1;
}
return {QWQ.first+1,QWQ.second+a[k]};
}
int main()
{
int n;
cin>>n>>L>>S;
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
for(int i=2;i<=n;i++)
{
int x;
scanf("%d",&x);
e[x].push_back(i);
}
memset(nex,0,sizeof nex);
memset(sum,0,sizeof sum);
for(int i=0;i<=20;i++)sum[0][i]=INF;
dfs(1,0);
cout<<ans<<endl;
return 0;
}
相關推薦
Codeforces-1059E:Split the Tree(貪心+倍增)
E. Split the Tree time limit per test 2 seconds memory limit per test 256 megabytes inputstandard input outputstandard output You a
Codeforces Round #514 (Div. 2) E. Split the Tree(貪心+倍增)
題意:給你一棵樹,問你最多能把這棵樹分成多少條鏈,使得每條鏈的長度不超過L,每條鏈上的點的權值和不超過S。 思路:這題是參考別人的思路,等有實力了自己再試試。。。從葉子往上貪心,每一次取能達到的最長鏈,也就是儘可能走到最遠的父親那裡,這裡採用樹上倍增處理,用top記錄每個節點最遠能去哪,然後從下
1059E Split the Tree(貪心+樹上倍增)
E. Split the Tree time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Y
Codeforces Round #514 (Div. 2) E. Split the Tree (貪心 + 樹上倍增)
題目大意:給出一棵有 n 個結點的樹,每個結點都有一個權值 w ,現在要你將這棵樹分成若干條鏈,且每個結點只能屬於一條鏈,分出來的鏈滿足每條鏈上的結點不超過L個,同時這些結點的權值和不超過S。問你最少能把這棵樹分成幾條鏈。 題目思路:由於是要使得鏈儘可能的少,所以分出來
【CodeForces - 1059E】Split the Tree
@Split the [email protected] @題目描述 - [email protected] @題目翻譯@ @分析@ @程式碼@ @[email protected]
CodeForces - 1098.DIV1.C: Construct a tree(貪心,構造)
Misha walked through the snowy forest and he was so fascinated by the trees to decide to draw his own tree! Misha would like to construct a rooted tree wi
CF 1039D You Are Given a Tree && CF1059E Split the Tree 的貪心解法
scanf sum turn namespace 試用 sin 這樣的 include clu 1039D 題意: 給你一棵樹,要求對給定鏈長於 k = 1, 2, 3, ..., n,求出最大的鏈剖分。 1059E 題意: 給你一棵帶權樹,要求對於一組給
Codeforces 980E The Number Games (貪心 + 倍增)
任重而道遠 The nation of Panel holds an annual show called The Number Games, where each district in the nation will be represented by one contestant. T
【CodeForces - 349B】Color the Fence (貪心,填數)
題幹: Igor has fallen in love with Tanya. Now Igor wants to show his feelings and write a number on the fence opposite to Tanya's house. Igor thinks
1059E】Split the Tree
@題目描述 - [email protected] time limit per test:2 seconds memory limit per test:256 megabytes You are given a rooted tree on n
2018東北四省賽 Split The Tree(區間種數的求法)
7229: Split The Tree 時間限制: 1 Sec 記憶體限制: 128 MB 提交: 68 解決: 18 [提交] [狀態] [討論版] [命題人:admin] 題目描述 You are given a tree with n vertices,
Codeforces1099D.Sum in the tree(貪心)
題目連結:傳送門 思路: 一個節點放的數越大,那麼以它為根的子樹的節點權值之和就越小。 所以我們要在合法的範圍內,使偶數層節點的權值儘可能地大。也就是說,令它的權值是子節點的最小值,這樣保證了它的子節點權值為正。 因為奇數層的節點的s已知,所以修改偶數層的節點僅影響,向下一層的節點。(因為
Codeforces 842C Ilya And The Tree(樹上DP+因子個數估計)
C. Ilya And The Tree time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard output
CodeForces-266A Stones on the Table(語法練習題)
Stones on the Table time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard output There are n stones
AtCoder Regular Contest 093 E: Bichrome Spanning Tree(生成樹)
包含 bool font return continue 找到 col include 情況下 Bichrome Spanning Tree 題意: 給出一個n個點,m條邊的無向連通圖,現在要給每條邊染色,可以染成黑色或者白色。 現在要求在染色完畢後,找出一個至少包含
CodeForces - 441D: Valera and Swaps(置換群)
numbers contain ron namespace opera 一個 pac element line A permutation p of length n is a sequence of distinct integers p1, p2,&thi
BZOJ4444 SCOI2015國旗計劃(貪心+倍增)
algorithm || end getc sort tdi sco color == 鏈上問題是一個經典的貪心。於是考慮破環成鏈,將鏈倍長。求出每個線段右邊能作為後繼的最遠線段,然後倍增即可。 #include<iostream> #include&l
Codeforces 1059E. Split the Tree
com href lan problems eps 節點 父節點 處理 sda 題目:http://codeforces.com/problemset/problem/1059/E 用倍增可以在nlog內求出每個節點占用一個sequence 時最遠可以向父節點延伸到的節點,
Codeforces 196C Paint Tree(貪心+極角排序)
cpp namespace paint 進行 滿足 sin its force 一個個 題目鏈接 Paint Tree 給你一棵n個點的樹和n個直角坐標系上的點,現在要把樹上的n個點映射到直角坐標系的n個點中,要求是除了在頂點處不能有線段的相交。 我們先選一個在直角坐標
HDU 4912 Paths on the tree(LCA+貪心)
path 同時 sort 我們 strong ble delta 選擇 所有 題目鏈接 Paths on the tree 來源 2014 多校聯合訓練第5場 Problem B 題意就是給出m條樹上的路徑,讓你求出可以同時選擇的互不相交的路徑最大數目。 我們先求出