Codeforces Round #530 (Div. 2)F Cookies

question:

Meaning of the questions: Given a tree, each node has information about the two of x and t, respectively, and the number of cookies upper hand on this node eat a biscuit on the node of the time. Then we have the upper hand and flip both individuals.

   ◉ upper hand can be so: In the specified total time T arrives at a node and then must return to the root node 1, you can choose to eat some cookies during on some nodes (the premise is to ensure that the rest of the time to return to the root node) ;

   ◉ flip can be so: Select the location and even between children reached this position just get the upper hand to eat more so that a side edge destroyed and you can skip this process; 

   Q: In a given total time T, just get the maximum number of cookies to eat.

Analysis: For each node has three choices, we write dp1, dp2, dp3;

   dp1: go up from the current position to eat up the biscuits;

   dp2: from the current position along the children go to eat the number of biscuits up; (this step only when the root of the work at the current location, because it is the upper hand, so you can directly choose maximum)

   dp3: from the current position to go along children to eat more than twice the number of cookies; (FLAC will prevent the upper hand because the maximum number of biscuits to eat, so we chose the second largest)

   dfs deal with this tree, back when doing dp2, you can calculate the dp3;

   Then we have the largest and the second largest t x and node information, the number of cookies for the full conversion time consuming, x * t x corresponds to eat a biscuit, then the answer can separate the two.

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define lson root<<1,l,midd
#define rson root<<1|1,midd+1,r
typedef long long ll;
const int M=1e6+5;
ll x[M],t[M];
struct node{
    int u;
    ll w;
};
vector<node>g[M];
struct Node{
    ll ti,num;
}tree[M<<2];
int n;
void update(ll num,ll ti,ll root,ll l,ll r){
    if(l==r){
        tree[root].ti+=num*ti;
        tree[root].num+=num;
        return ;
    }
    int midd=(l+r)>>1;
    if(ti<=midd)
        update(num,ti,lson);
    else
        update(num,ti,rson);
    tree[root].ti=tree[root<<1].ti+tree[root<<1|1].ti;
    tree[root].num=tree[root<<1].num+tree[root<<1|1].num;
} 
ll query(ll nowti,ll root,ll l,ll r){
    if(tree[root].ti<=nowti)
        return tree[root].num;    
    if(l==r)
        return nowti/l;
    int midd=(l+r)>>1;
    if(tree[root<<1].ti>=nowti)
        return query(nowti,lson);
    else
        return query(nowti-tree[root<<1].ti,rson)+tree[root<<1].num;
}
ll dfs(int u,ll nowt){
    //cout<<u<<endl;
    update(x[u],t[u],1,1,1000000);
    ll dp1=query(nowt,1,1,1000000);
    ll dp2=0,dp3=0;
    for(int i=0;i<g[u].size();i++){
        node v=g[u][i];
        if(nowt<=2*v.w)
            continue;
        ll temp=dfs(v.u,nowt-2ll*v.w);
        if(temp>dp2)
            dp3=dp2,dp2=temp;
        the else if(DP3 < TEMP) 
            DP3 = TEMP; 
    } 
    Update ( the -X-[U], T [U], . 1 , . 1 , 1000000 );
     IF (U == . 1 ) /// root node, go, so we do not consider the time large 
        return max (DP1, DP2 is);
     the else 
        return max (DP1, DP3); 
} 
int main () { 
    LL T; 
    Scanf ( " % D% I64d " , & n-, & T);
     for ( int I = . 1 ; I <= n-; I ++ ) 
        Scanf ( " % I64d ",&x[i]);
    for(int i=1;i<=n;i++)
        scanf("%I64d",&t[i]);
    for(int i=2;i<=n;i++){
        ll w;
        int u;
        scanf("%d%I64d",&u,&w);
        g[u].pb(node{i,w});
    }
    printf("%I64d",dfs(1,T));
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/starve/p/12003889.html