题目链接:传送门

思路:

  分析到处理节点时的吃cookie的顺序了,然鹅不会用线段树维护前缀和。技术门槛QAQ。。。

  很容易想到可以从root开始搜索,每次深入消耗时间2*边权w。

  然后对于深入到点u开始返回的话,想要尽量多地吃cookie,就要贪心地选择用时短的cookie,也就是:

    当前节点为u,剩余时间为val时,最多能在1-u这条链上吃到多少个cookie。

  一共有1e6个节点,所以这个贪心策略的实现复杂度要压到log级别。。。好难不会。


思路参考:Dream_maker_yk的博客

  线段树维护前缀和。

  首先我们以时间ti为坐标向线段树中插入节点。保存两个值,把子树吃光所用的总时间sum,子树中的cookie总数cnt。

  然后根据剩余时间val查询,如果左子树的sum比val小,那么说明左子树可以吃光,那么查询结果就是:

    cnt左子树 + 对右子树查询val - sum左子树

  这样我们就可以用logn的时间实现贪心策略了。


  然后考虑到Vasya会干扰我们,所以应题目要求,我们要求在Vasya干扰得最好的情况下,能吃到的最大的cookie数量。

  最差的情况就是Vasya每次深入后都把最好的子树f1给办掉了,那么我们只能选次好的子树f2。

  因为每个节点都可能返回,所以回溯当前节点的最多cookie数ans。而当前节点的最多cookie数可能是吃到当前节点为止,也可能是吃到当前节点的子树,所以ans = max(ans,f2)。

  特别地,因为Mitya是先手,所以root的子树不会被办,ans = max(ans,f1)。

代码:

#include <bits/stdc++.h>
#define lson (pos << 1)
#define rson (pos << 1 | 1) using namespace std;
typedef long long ll;
const int MAX_N = 1e6 + ; struct Edge{
int v;
ll w;
};
ll x[MAX_N], t[MAX_N];
vector <Edge> g[MAX_N]; ll sum[MAX_N<<], cnt[MAX_N<<]; void update(int pos, int l, int r, ll xi, ll ti) {
sum[pos] += xi*ti;
cnt[pos] += xi;
if (l == r)
return;
int mid = (l + r) >> ;
if (ti <= mid)
update(lson, l, mid, xi, ti);
else
update(rson, mid+, r, xi, ti);
} ll query(int pos, int l, int r, ll val) {
if (l == r)
return min(cnt[pos], val/l);
int mid = (l + r) >> ;
if (sum[lson] <= val)
return cnt[lson] + query(rson, mid+, r, val - sum[lson]);
else
return query(lson, l, mid, val);
} ll dfs(int u, ll res) {
update(, , 1e6, x[u], t[u]);
ll ans = query(, , 1e6, res);
ll f1 = , f2 = ;
for (const auto &tmp : g[u]) {
int v = tmp.v;
ll w = tmp.w;
if (res < *w)
continue;
ll f = dfs(v, res - *w);
if (f > f1)
f2 = f1, f1 = f;
else if (f > f2)
f2 = f;
}
update(, , 1e6, -x[u], t[u]);
if (u == )
return max(ans, f1);
else
return max(ans, f2);
} int main()
{
std::ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
ll T;
cin >> n >> T;
for (int i = ; i <= n; i++)
cin >> x[i];
for (int i = ; i <= n; i++)
cin >> t[i];
for (int u = ; u <= n; u++) {
int v;
ll w;
cin >> v >> w;
g[v].push_back((Edge){u, w});
} ll ans = dfs(, T); cout << ans << endl;
return ;
}

Codeforces1099F. Cookies(线段树+dp+贪心+博弈)的更多相关文章

  1. 线段树+dp+贪心 Codeforces Round #353 (Div. 2) E

    http://codeforces.com/contest/675/problem/E 题目大意:有n个车站,每个车站只能买一张票,这张票能从i+1到a[i].定义p[i][j]为从i到j所需要买的最 ...

  2. Codeforces Gym 100231B Intervals 线段树+二分+贪心

    Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...

  3. Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)

    [题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...

  4. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  5. 【arc073e】Ball Coloring(线段树,贪心)

    [arc073e]Ball Coloring(线段树,贪心) 题面 AtCoder 洛谷 题解 大型翻车现场,菊队完美压中男神的模拟题 首先钦定全局最小值为红色,剩下的袋子按照其中较大值排序. 枚举前 ...

  6. 【agc028E】High Elements(动态规划,线段树,贪心)

    [agc028E]High Elements(动态规划,线段树,贪心) 题面 AtCoder 你有一个\([1,N]\)的排列\(P\). 一个长度为\(N\)的字符串\(S\)是好的,当且仅当: 两 ...

  7. POJ.1769.Minimizing maximizer(线段树 DP)

    题目链接 /* 题意:有m个区间,问最少要多少个区间能覆盖[1,n] 注:区间要按原区间的顺序,不能用排序贪心做 设dp[i]表示最右端端点为i时的最小值 dp[e[i]]=min{dp[s[i]]~ ...

  8. 【BZOJ】1664: [Usaco2006 Open]County Fair Events 参加节日庆祝(线段树+dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1664 和之前的那题一样啊.. 只不过权值变为了1.. 同样用线段树维护区间,然后在区间范围内dp. ...

  9. POJ1769(线段树+DP)

    飞翔 题意 : 给定一个区间长度 n ,接下来给出 m 个子区间,要求最少选出多少个区间才能使得 1~n 这个区间被所选的所有子区间覆盖 分析: 首先是动态规划,dp[i]表示把最大值从1位置搞到第i ...

随机推荐

  1. https环境搭建(本地搭建)

    1.创建自签名证书 2. 在iis中绑定https 先解析一个域名. 运行网站 示不安全,点击继续浏览即可.在实际的环境中,你拿到的是一个实际的证书,所以不会产生类似的报告安全证书有问题.

  2. mybatis-spring和spring版本搭配问题

    所报错误:org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()Ljava/lang/Integer 匹配的版本(my ...

  3. js dictionary

    转载的 1.dictionary例子 <script type="text/javascript" language="javascript"> v ...

  4. 用git提交源代码

    码云账号 markliuning      作业已经上传 题目要求:定义一个包含有10个整数的数组a并初始化,定义一个指针变量p,p指向数组a,定义函数fun,在fun内部访问数组,并打印出数组中各元 ...

  5. onmouseover与onmouseenter区别

    1.onmouseover.onmouseout:鼠标经过时自身触发事件,经过其子元素时也触发该事件:(父亲有的东西,儿子也有) ,支持冒泡 2.onmouseenter.onmouseleave:鼠 ...

  6. 进程pid理解

    PID(Process Identification)操作系统里指进程识别号,也就是进程标识符.操作系统里每打开一个程序都会创建一个进程ID,即PID.   PID(进程控制符)英文全称为Proces ...

  7. centos7 无界面静默安装 oracle

    环境准备 Centos7.3.64  64位   这里使用的是阿里云 ECS主机(1核,2G内存,40G硬盘) Oracle 11g R2 64位安装介质(版本11.2.0.1)下载地址:http:/ ...

  8. type-of-python作业-判断字符串是否属于回文需要忽略其中的标点、空格与大小写

    type-of-python作业 作业练习:要想检查文本是否属于回文需要忽略其中的标点.空格与大小写.例如,"Rise to vote, sir."是一段回文文本,但是我们现有的程 ...

  9. io复用select方法编写的服务器

    摘要:io多路复用是通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般都是读就绪或者写就绪),就能通知应用程序进行相应的读写操作.select函数作为io多路复用的机制,第一个参数nfds是f ...

  10. shell_base

    1.使用if_then语句if command then commands fi 先运行if后面的命令,如果命令的退出状态是0(成功执行命令),就将执行then后面,fi前面的所有命令.否则就跳到fi ...