1. 程式人生 > >Codeforces-1059E:Split the Tree(貪心+倍增)

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 wiw_i. 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 w

iw_i on each path does not exceed S. Each vertex should belong to exactly one path.

A vertical path is a sequence of vertices v1,v2,,vkv_1,v_2,…,v_k where vi(i2)v_i (i≥2) is the parent of vi1v_{i−1}.

Input
The first line contains three integers n, L, S (1n105,1L105,

1S1018)(1≤n≤10^5, 1≤L≤10^5, 1≤S≤10^{18}) — 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 w1,w2,,wn(1wi109)w_1,w_2,…,w_n (1≤w_i≤10^9) — the numbers in the vertices of the tree.

The third line contains n−1 integers p2,,pn(1pi<i)p_2,…,p_n (1≤p_i<i), where pip_i 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-1059ESplit 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 - 1059ESplit 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

1059ESplit 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 treeLCA+貪心

path 同時 sort 我們 strong ble delta 選擇 所有 題目鏈接 Paths on the tree 來源 2014 多校聯合訓練第5場 Problem B 題意就是給出m條樹上的路徑,讓你求出可以同時選擇的互不相交的路徑最大數目。 我們先求出