「joisc 2019 - d2t2」ふたつの料理 Two Dishes
[link。](E - ふたつの料理 (Two Dishes) (atcoder.jp)
我要放假
神仙题。
首先可以把两根轴拉成平面(which is a common trick),把决策的过程看作从 \((0, 0)\) 走到 \((n, m)\),每次可以往上走或往右走(左下为 (0, 0),右上是 (n, m))。考虑相对于我们走出的决策路线表现出了怎样特征的点会对答案造成贡献。对于 A 套餐的操作 \(i\) 处理出 \(x_i\),表示做完了 A 套餐的前 i 个操作,最多还能做到 B 套餐的 x_i 操作,同理处理出 \(y_j\)。
把 \((i, x_i)\),\((y_j, j)\) 看作点放到平面上,当 \((i, x_i)\) 在路径上方是获得 \(p_i\) 的贡献,当 \((y_j, j)\) 在路径当中或下方时获得 \(q_j\) 的贡献。可以先把 p_i 全部加上然后取反转化调整到和 q_j 同样的贡献条件。
那么现在问题是:给出平面,找出一条从 (0, 0) 到 (n, m) 的路径,使得路径当中以及以下的点权和最大。
考虑 dp,设 \(f[i][j]\) 为走到 (i, j) 的最优答案。令 \(s[i][j]\) 为点 \((i, j)\) 正下方以及自己的点权和,然后我们发现无论从上一行还是上一列转移写出来都不对劲(\(dp[i][j] = dp[i-1][j]+f_1(i, j)+dp[i][j-1]+f_2(i, j)\) 的形式,不好优化),我们考虑从拐点转移(这一步很神奇,同时这一步也是我觉得整道题最 tricky 的地方,但是网上的题解都太草率了,给的转移也不能让我信服),写出的 transitions 是 \(\displaystyle dp[i][j] = \max_{k \leqslant j}\{dp[i-1][k]\}+s[i][j]\),自己画一个先右再上的折箭头就理解了。
考察转移发现我们有太多的无用转移,注意到平面中权重非 0 的点只有 \(O(n+m)\) 个,于是我们考虑非 0 点。首先把 s[i][j] 拆成 \(w_{0, j}+w_{1, j}+\dots +w_{i, j}\),这样我们的区间修改就是区间加定值而不是加一个毫无特征的序列了。再考虑前缀 max,因为我们是差分数组,我们只需要将 diff array 中的负项删除,并删除其影响,最后一位即是最大值。
/*
lyddnb
dp[i][j] = max[k <= j]{dp[i-1][k]}+s[i][j]
dp[i]: foreach j, j = premax, j += s[i][j]
*/
int n, m, p[1000100], q[1000100];
ll a[1000100], b[1000100], s[1000100], t[1000100], ans, dif[1000100];
vi<pil> g[1000100]; // g[i](x, y) point (i, x) with weight y
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; ++i) cin >> a[i] >> s[i] >> p[i], a[i] += a[i - 1];
for (int i = 1; i <= m; ++i) cin >> b[i] >> t[i] >> q[i], b[i] += b[i - 1];
for (int i = 1; i <= n; ++i) {
if (a[i] > s[i]) continue;
int j = upper_bound(b + 1, b + m + 1, s[i] - a[i]) - b;
ans += p[i], g[i].eb(j, -p[i]);
}
for (int i = 1; i <= m; ++i) {
if (b[i] > t[i]) continue;
if (b[i] + a[n] <= t[i])
ans += q[i];
else {
int j = upper_bound(a + 1, a + n + 1, t[i] - b[i]) - a;
g[j].eb(i, q[i]);
}
}
set<int> st;
for (int i = 0; i <= n; ++i) {
sort(g[i].begin(), g[i].end());
for (auto const& [x, y] : g[i]) {
if (x <= m) {
if (!st.count(x)) st.insert(x), dif[x] = 0;
dif[x] += y;
}
}
for (auto const& [x, ignore] : g[i]) {
if (x > m) continue;
auto it = st.find(x);
while (it != st.end() && dif[*it] < 0) {
ll tmp = dif[*it];
it = st.erase(it);
if (it != st.end()) dif[*it] += tmp;
}
}
}
for (auto x : st) ans += dif[x];
cout << ans << "\n";
}
「joisc 2019 - d2t2」ふたつの料理 Two Dishes的更多相关文章
- 【LOJ】#3034. 「JOISC 2019 Day2」两道料理
LOJ#3034. 「JOISC 2019 Day2」两道料理 找出最大的\(y_{i}\)使得\(sumA_{i} + sumB_{y_i} \leq S_{i}\) 和最大的\(x_{j}\)使得 ...
- 「JOISC 2019 Day3」穿越时空 Bitaro
「JOISC 2019 Day3」穿越时空 Bitaro 题解: 不会处理时间流逝,我去看了一眼题解的图,最重要的转换就是把(X,Y)改成(X,Y-X)这样就不会斜着走了. 问题变成二维平面上 ...
- 【LOJ】#3036. 「JOISC 2019 Day3」指定城市
LOJ#3036. 「JOISC 2019 Day3」指定城市 一个点的可以dp出来 两个点也可以dp出来 后面的就是在两个点的情况下选一条最长的链加进去,用线段树维护即可 #include < ...
- 【LOJ】#3032. 「JOISC 2019 Day1」馕
LOJ#3032. 「JOISC 2019 Day1」馕 处理出每个人把馕切成N段,每一段快乐度相同,我们选择第一个排在最前的人分给他的第一段,然后再在未选取的的人中选一个第二个排在最前的切一下,并把 ...
- 【LOJ】#3033. 「JOISC 2019 Day2」两个天线
LOJ#3033. 「JOISC 2019 Day2」两个天线 用后面的天线更新前面的天线,线段树上存历史版本的最大值 也就是线段树需要维护历史版本的最大值,后面的天线的标记中最大的那个和最小的那个, ...
- 【LOJ】#3031. 「JOISC 2019 Day1」聚会
LOJ#3031. 「JOISC 2019 Day1」聚会 听说随机可过? 我想了很久想了一个不会被卡的做法,建出前\(u - 1\)个点的虚树,然后找第\(u\)个点的插入位置,就是每次找一条最长链 ...
- 【LOJ】#3030. 「JOISC 2019 Day1」考试
LOJ#3030. 「JOISC 2019 Day1」考试 看起来求一个奇怪图形(两条和坐标轴平行的线被切掉了一个角)内包括的点个数 too naive! 首先熟练的转化求不被这个图形包含的个数 -- ...
- @loj - 3039@ 「JOISC 2019 Day4」蛋糕拼接 3
目录 @description@ @solution@ @accepted code@ @details@ @description@ 今天是 IOI 酱的生日,所以她的哥哥 JOI 君给她预定了一个 ...
- 「JOISC 2019 Day4」蛋糕拼接 3
loj 3039 NKOJ Description \(n\)个蛋糕,每个蛋糕有\(w_i,h_i\).选\(m\)个蛋糕满足\(\sum\limits_{j=1}^mw_{k_j}-\sum\lim ...
- 【LOJ】#3014. 「JOI 2019 Final」独特的城市(长链剖分)
LOJ#3014. 「JOI 2019 Final」独特的城市(长链剖分) 显然我们画一条直径,容易发现被统计的只可能是直径某个距离较远的端点到这个点的路径上的值 用一个栈统计可以被统计的点,然后我们 ...
随机推荐
- ORM总览
ORM(Object-Relational Mapping)是一种常见的数据访问技术,它将对象模型和关系模型之间进行映射.ORM的主要作用是简化数据访问和管理,提高开发效率和代码质量.在实际应用中,O ...
- 前端检测手机系统是iOS还是android(可实现根据手机系统跳转App下载链接)
快速实现前端检测手机系统是iOS还是android(可实现根据手机系统跳转App下载链接); 下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plug ...
- string类型可以作为lock的锁对象吗
lock 关键字介绍 lock 关键字是用于在多线程编程中实现同步和互斥访问的关键字.它的作用是确保共享资源在任意时刻只能被一个线程访问,从而避免出现竞态条件(race condition)和数据不一 ...
- Linux下AWK、SED、GREP、FIND命令详解
AWK AWK是一个优良的文本处理工具,Linux和Unix环境中现有的功能最强大的数据处理引擎之一. 语法 awk [选项参数] 'script' var=value file(s) 或 awk [ ...
- Mininet教程
mininet的安装 1.前言 1.本次安装环境为ubuntu20.04. 2.mininet 为 github上的最新版,我已经修改镜像地址并克隆到了gitee,只需要从我的gitee仓库克隆即可. ...
- 应用CS5266设计一款TYPEC转HDMI带PD3.0+USB3.1扩展坞方案电路图
目前市场TYPEC扩展坞有很多,基本都是大同小异,主要功能是TYPEC转HDMI带PD+USB3.1+RJ45+SD/TF读卡器等多种接口,由于产品类型较多,成本也都是越做越低,CS瑞奇达就开发一系列 ...
- 【小小Demo】网页视频通话小🌰子
工程名 video-call 一个简单的 音视频通话 demo,包含:视频.麦克风.屏幕共享操作. 项目环境 jdk1.8 idea maven springboot 2.1.1.RELEASE we ...
- git 访问仓库错误
通过https访问git出现错误, failed: Error in the pull function 尝试将https改为http
- MASABlazor在移动端点击保持出现悬停样式
提出问题 最近在学习MAUIBlazor,用的MASA Blazor,发现在移动端(触屏设备)上,点击会一直显示悬停样式,如下图所示,简单研究了一下,发现这是移动端的通病. 解决问题 MASABlaz ...
- 2021-7-30 MySql函数的使用归类整理
Mysql字符的使用 SELECT ASCII(user_password) as 阿斯克码 FROM users;#返回首字符的ascii码 SELECT CHAR_LENGTH(user_pass ...