$$AVICII$$

Codeforces 1099F Cookies

Problem - 1099F - Codeforces

 

给一棵树,边权为时间花费,每个节点有t[i]表示在这个节点吃一个cookie花的时间,x[i]表示这个节点cookie的个数,给了限制时间T

A先手移动从根节点,每次移动到子节点或者返回,返回途中吃cookie

B后手可以选择阻止A到达某个子节点

问可以吃到的最大的数量

假设到达点u后开始返回,即用T-边权和的时间尽可能的多吃,可以以这条到根的链上的t为下标建立线段树,二分贪心询问最大的数量

其次是考虑有B的限制问题,所以可以求dp,表示从u点的最优决策值

首先是从u返回的值

其次是在u的子节点里选择继承,但是因为B的限制要选次大值(除了根节点,因为先手)

 

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4 const int MAXN=1e6+17;
 5 const int lim=1e6;
 6 LL T;
 7 int n;
 8 int x[MAXN],t[MAXN];
 9 vector<pair<int ,int > >to[MAXN];
10 struct segment_tree{
11     #define ls (u<<1)
12     #define rs (u<<1|1)
13     LL num[MAXN<<2],sm[MAXN<<2];
14     void up(int u){
15         num[u]=num[ls]+num[rs];
16         sm[u]=sm[ls]+sm[rs];
17         return ;
18     }
19     void build(int u,int l,int r){
20         sm[u]=num[u]=0;
21         if(l==r)return ;
22         int mid=l+r>>1;
23         build(ls,l,mid),build(rs,mid+1,r);
24         return up(u);
25     }
26     LL query(int u,int l,int r,LL ssm){
27         if(sm[u]==0)return 0;
28         // cout<<u<<" "<<l<<" "<<r<<" "<<ssm<<" "<<sm[ls]<<" "<<sm[rs]<<endl;
29         if(l==r)return min(ssm/l,num[u]);
30         int mid=l+r>>1;
31         if(sm[ls]>=ssm)return query(ls,l,mid,ssm);
32         else return num[ls]+query(rs,mid+1,r,ssm-sm[ls]);
33     }
34     void modify(int u,int l,int r,int pos,LL nnm){
35         // cout<<u<<" "<<l<<" "<<r<<" "<<pos<<" "<<nnm<<endl;
36         if(l==r){
37             num[u]+=nnm;
38             sm[u]+=nnm*pos;
39             return ;
40         }
41         int mid=l+r>>1;
42         if(pos<=mid)modify(ls,l,mid,pos,nnm);
43         else modify(rs,mid+1,r,pos,nnm);
44         return up(u);
45     }
46 }tr;
47 LL dfs(int u,LL rem){
48     // cout<<"FSDFDSS "<<u<<" "<<rem<<" "<<t[u]<<" "<<x[u]<<endl;
49     tr.modify(1,1,lim,t[u],x[u]);
50     LL res=tr.query(1,1,lim,rem);
51     // cout<<u<<" "<<res<<endl;
52     LL mx1=0,mx2=0;
53     for(int i=0;i<to[u].size();++i){
54         pair<int ,int >y=to[u][i];
55         if(rem-y.second<=0)continue;
56         LL t=dfs(y.first,rem-y.second);
57         if(t>=mx1)mx2=mx1,mx1=t;
58         else if(t>mx2)mx2=t;
59     }
60 
61     tr.modify(1,1,lim,t[u],-x[u]);
62     if(u==1)res=max(res,mx1);
63     // cout<<u<<" "<<max(res,mx2)<<" "<<rem<<endl;
64     return max(res,mx2);
65 }
66 int main(){
67     scanf("%d%lld",&n,&T);
68     tr.build(1,1,lim);
69     for(int i=1;i<=n;++i)scanf("%d",&x[i]);
70     for(int i=1;i<=n;++i)scanf("%d",&t[i]);
71     for(int i=2,p,l;i<=n;++i){
72         scanf("%d%d",&p,&l);
73         to[p].push_back(make_pair(i,l*2));
74     }
75     printf("%lld\n",dfs(1,T));
76     return 0;
77 }
View Code

 

posted @ 2022-07-04 11:25  bootpuss  阅读(37)  评论(0编辑  收藏  举报