\(\text{Problem - 889E - Codeforces}\) \(\text{*3000}\)

修正

感谢学长 \(\text{fs}\) 指出状态数原因解释的错误。

题意

给一个序列,对于一个非负整数 \(x\),有一个式子:

\[x\bmod a_1+x\bmod a_1\bmod a_2+...+x\bmod a_1\bmod a_2...\bmod a_n
\]

求出上式的最大值。

思路

先去寻找题目的性质。

首先 \(x\) 的值单调不增,然后如果当前 \(x\) 的值小于 \(a_i\) 则对 \(x\) 无影响。

对于上述两条,我们首先能够总结出一点:一定存在一个答案区间 \([l,r]\),其中 \(ans_l=ans_r=a_l-1\)。说人话就是首先答案是一段一段的递减区间,然后一定有一段区间的值顶着对应区间的上界。因为如果没有,则可以至少令当前 \(x+1\),然后答案更大。然后就是 \(x+1\) 的操作的正确性是因为余数性质:\(x+y\equiv x\%p+y\%p\pmod p\),所以只要操作后 \(x\) 小于 \(p\) 后面区间就不会变成零,并且我如果将最初的 \(x+1\),那么所有位置的 \(x\) 就都会加一,答案也都会加一。

然后对于这道题有一个显然的暴力 \(dp\)。我们令 \(f_{i,j}\) 表示计算到位置 \(i\) 当前 \(x\) 值为 \(j\) 的最大值,转移显然,复杂度是 \(O(n\times a_1)\)。

考虑能否优化状态。因为答案区间是一段一段的递减,其实我们枚举 \(j\) 的时候就会发现最下面的答案是 \(i\times j\),然后上面变成一段更小的单调不增的区间。然后根据之前发现每个位置对应的 \(x\) 同加同减,也就是说他们的相对值不变,所以如果我们不去维护最后的答案而是只维护上层的答案,那么更新(转移)上面的答案就是 \(O(1)\) 的。比如我转移状态需要修改 \(x\) 时,我只需要把区间整体答案修改即可。

所以我们得到了最终的 \(dp\),设 \(f_{i,j}\) 表示计算到位置 \(i\) 当前 \(x\) 值为 \(j\) 时每个 \(x\) 大于 \(j\) 的部分的和,最后答案就是 \(\max_{0\le i<a_n} \{f_{n,i}+n\times i\}\)。转移时对于 \(f_{i,j}\) 分成两种情况考虑:

  1. 直接转移到 \(f_{i+1,j\%a_{i+1}}\):这时 \(j\) 变小,答案加上 \(j-j\%a_{i+1}\) 的高度;
  2. 每次新维护一个 \(f_{i+1,a_{i+1}-1}\):答案加上的高度类比第一种即可。

存在第二种转移是因为性质一告诉我们一定会有一个 \(x=a_i-1\),所以每次需要维护。

关于复杂度的话,考虑对于每个 \(i\),至多存在 \(0,1,2...,a_i-1\) 一共 \(a_i\) 种状态,所以初始状态可看成 \(n\) 种;每次转移会将 \(j\) 转移到 \(j\% a_i\) 上,又因为每次取模 \(j\) 至少减半,所以状态是 \(n\log x\) 的。然后实际 \(dp\) 的时候,第一维滚掉,第二维发现 \(j\) 太大用 \(\text{map}\) 存,然后 \(\text{map}\) 也有一只 \(\log\),所以时间复杂度是 \(O(n\log x\log n)\)。

代码

signed main(){
n = rd(), res[p = rd() - 1] = 0;
for(int i = 2; i <= n; ++i){
p = rd();
for(map < ll , ll > :: iterator it = res.lower_bound(p); it != res.end(); res.erase(it++)){
ll j = (*it).first, f = (*it).second;
res[j % p] = max(res[j % p], f + (i - 1) * (j - j % p));
res[p - 1] = max(res[p - 1], f + (i - 1) * ((j + 1) / p * p - p));
}
}
for(map < ll , ll > :: iterator it = res.begin(); it != res.end(); it++)ans = max(ans, n * (*it).first + (*it).second);
printf("%lld", ans);
return 0;
}

CF889E题解的更多相关文章

  1. 【CF889E】Mod Mod Mod DP

    [CF889E]Mod Mod Mod 题意:给你一个序列$a_1,a_2...a_n$,定义$f(x,n)=x\mod a_n$,$f(x,i)=x\mod a_i+f(x \mod a_i,i+1 ...

  2. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  3. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  4. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  5. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  6. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  7. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  8. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  9. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  10. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. 拥抱云原生,数据湖加速器 GooseFS 助力 Fluid 数据缓存实现

    01 ​前言 数据湖加速器 GooseFS 是由腾讯云推出的高性能.高可用.弹性的分布式缓存方案.依靠对象存储(Cloud Object Storage,COS)作为数据湖存储底座的成本优势,为数据湖 ...

  2. COSBrowser iOS 版 | 如何不打开 App 查看监控数据?

    您是否有遇到这样的场景?当需要实时查看存储监控数据.查看某个存储桶的对象数量,又或者想了解某一个存储类型文件的下载量在当前与前一天的对比情况,是上涨了还是下降了,这时您是否也在经历频繁的打开关闭 Ap ...

  3. IOS多线程之NSOperation(3)

    IOS多线程之NSOperation(3) 操作优先级和服务质量 可以通过QueuePriority属性来设置operation在队列中的执行优先级 public enum QueuePriority ...

  4. Flutter ListView顶部空白去除

    Flutter ListView顶部空白去除 当listview没有和AppBar一起使用时,顶部会有一个自动的空白部分,可以用MediaQuery.removePadding去掉 return Me ...

  5. showModalBottomSheet setState 无法更新ui和高度设置问题

    showModalBottomSheet setState 无法更新ui问题 首先理解showModalBottomSheet,本质上可以理解为路由入栈,在show之后弹出的页面其实是另一个页面了,此 ...

  6. c++死锁调试 ,gdb pstack

    psatck ‌pstack命令‌是一个在Linux系统中用于查看进程堆栈信息的工具. 写了一个服务端死锁程序,如下: #include <iostream> #include <t ...

  7. C#反序列化时,反射类型“XXX”时出错,提示:InvalidOperationException

    C#反序列化时,反射类型"XXX"时出错,提示:InvalidOperationException的原因是因为: 一个类必须至少有一个空的默认构造函数,才能由XmlSerializ ...

  8. IM跨平台技术学习(八):新QQ桌面版为何选择Electron作为跨端框架

    本文由QQ技术团队王辉.吴浩.陈俊文分享,编辑Tina整理,本文收录时有内容修订和排版优化. 1.引言 在瞬息万变的互联网行业中,年过二十四的即时通讯IM应用 QQ 堪称超长寿的产品,见证了中国互联网 ...

  9. 飞书lark机器人 自动化发版

    飞书lark机器人 自动化发版 #1 介绍 开发飞书机器人接收消息并调用构建接口, 实现自动化发版 发送指令 -> 机器人接收指令 -> 调用jenkins-job远程构建与部署 jenk ...

  10. wpf ScrollViewer 滚动动画

    wpf ScrollViewer 滚动动画: <Window x:Class="WpfTest.FloatTextWindow" xmlns="http://sch ...