【题解】CF#713 E-Sonya Partymaker
这题真的想了挺久的,然而到最后也还是没想到怎样处理环的情况……网上竟然也完全没有题解,无奈之下到 CF 的 AC 代码里面去找了一份膜拜了一下。感谢~
由于觉得这题有一定的难度,自己看代码也看了比较久才理解,就记录一下吧……
首先,不难发现一个人一定不会往返走。因为一个人之所以要往回走,理由一定是因为碰到了已经访问过的凳子(与他人的路径相撞)。我们不妨看作是这两个人灵魂交换,即两人均继续向前,而不往返。所以问题转化为在一个环上指定 n 个点,从每个点可以顺 \ 逆时针延伸出一条长为 x 的线段,问能覆盖整个环的最小 x 值。
显然需要二分一下。如果这个问题是在序列上的问题,我们可以 dp。设立 dp 状态 f[i][0 / 1] 表示第 i 号节点是向左 / 向右的线段,所能从起点开始连续访问的最远地点是多少。这样好像有个 bug :可以有下图中的情况出现,即第 i - 1 到第 i 号节点之间的位置由第 i + 1 号节点来覆盖。但这样没有关系,因为我们可以在 dp 到 i + 1 的位置的时候填补起 i ~ i - 1 之间的位置,并把答案更新为第 i 号节点向前延伸出来的部分。
如果不够清晰,可以看一下代码中的转移方程。
最难处理的就是这一个环。因为有可能第 1 号节点和第 2 号节点之间的这一段是由第 n 号节点来覆盖的。可是这样根据我们的定义,我们将一直无法更新 dp 数组。为了避免这样的一种情况,我们可以选择破环为链。断开哪一条边呢?选择断开最长的一条边,因为这条边就是答案的上界,也就是指这样断开的链上 n 号节点永远不会选择通过这条边来覆盖 1~2 之间的这一段。然后我们就只需要分类讨论一下 1 号节点是向左还是向右就可以了。
**启示:其实这种破环为链的题目见得很多了,但还是没有做出来,是我太菜了……应该找到在环上必然不会有影响的一条边去分割成链,如51nod部落信号。
代码(kuai的...):
#include <bits/stdc++.h>
using namespace std;
#define maxn 1000000
#define int long long
#define INF 99999999999LL
int n, m, f[maxn][], P[maxn], p[maxn];
int ans, mx, pos; int read()
{
int x = , k = ;
char c; c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} bool Check(int x)
{
for(int j = ; j <= ; j ++)
{
f[][] = j ? -INF : ; f[][] = j ? x : -INF;
if(j)
{
if(x + >= P[]) f[][] = max(P[] + x, P[]);
else f[][] = -INF;
}
for(int i = j + ; i <= n; i ++)
{
f[i][] = f[i][] = max(f[i - ][], f[i - ][]);
if(max(f[i - ][], f[i - ][]) + >= P[i]) f[i][] = P[i] + x;
if(P[i] - x - <= f[i - ][]) f[i][] = max(f[i - ][], P[i]);
if(P[i] - x - <= f[i - ][]) f[i][] = max(f[i - ][], max(P[i], P[i - ] + x));
}
int t = max(f[n][], f[n][]);
if(j && t + >= P[] + m - x) return ;
else if(!j && t + >= m - x) return ;
}
return ;
} signed main()
{
m = read(), n = read();
if(n == ) { printf("%I64d\n", m - ); return ; }
for(int i = ; i <= n; i ++) p[i] = read();
for(int i = ; i <= n; i ++)
{
int dis; dis = p[i] - p[i - ];
if(i == ) dis = p[i] + m - p[n];
if(dis > mx) mx = dis, pos = i;
} for(int i = ; i <= n; i ++)
{
int t = i - + pos; if(t > n) t -= n;
P[i] = p[t]; P[i] -= p[pos];
if(P[i] < ) P[i] += m;
} int l = , r = m - ;
while(l <= r)
{
int mid = (l + r) >> ;
if(Check(mid)) ans = mid, r = mid - ;
else l = mid + ;
}
printf("%I64d\n", ans);
return ;
}
【题解】CF#713 E-Sonya Partymaker的更多相关文章
- 【CodeForces】713 C. Sonya and Problem Wihtout a Legend
[题目]C. Sonya and Problem Wihtout a Legend [题意]给定n个数字,每次操作可以对一个数字±1,求最少操作次数使数列递增.n<=10^5. [算法]动态规划 ...
- 竞赛题解 - CF Round #524 Div.2
CF Round #524 Div.2 - 竞赛题解 不容易CF有一场下午的比赛,开心的和一个神犇一起报了名 被虐爆--前两题水过去,第三题卡了好久,第四题毫无头绪QwQ Codeforces 传送门 ...
- Codeforces 713 C Sonya and Problem Wihtout a Legend
Description Sonya was unable to think of a story for this problem, so here comes the formal descript ...
- 题解——CF Manthan, Codefest 18 (rated, Div. 1 + Div. 2) T5(思维)
还是dfs? 好像自己写的有锅 过不去 看了题解修改了才过qwq #include <cstdio> #include <algorithm> #include <cst ...
- 竞赛题解 - [CF 1080D]Olya and magical square
Olya and magical square - 竞赛题解 借鉴了一下神犇tly的博客QwQ(还是打一下广告) 终于弄懂了 Codeforces 传送门 『题目』(直接上翻译了) 给一个边长为 \( ...
- [题解] [CF 1250J] The Parade
题面 题目大意: 给定一个 \(n\) , 所有军人的数量均在 \([1, n]\) 给定 \(a_i\) 代表高度为 \(i\) 的军人的个数 你要将这些军人分成 \(k\) 行, 满足下面两个条件 ...
- 题解 CF 1372 B
题目 传送门 题意 给出 \(n\),输出 \(a\) ,\(b\) (\(0 < a \leq b < n\)),使\(a+b=n\)且 \(\operatorname{lcm}(a,b ...
- 题解——CF Manthan, Codefest 18 (rated, Div. 1 + Div. 2) T4(模拟)
随便模拟下就过了qwq 然后忘了特判WA了QwQ #include <cstdio> #include <algorithm> #include <cstring> ...
- 题解——CF Manthan, Codefest 18 (rated, Div. 1 + Div. 2) T3(贪心)
是一道水题 虽然看起来像是DP,但其实是贪心 扫一遍就A了 QwQ #include <cstdio> #include <algorithm> #include <cs ...
随机推荐
- 可能是全网首个支持阿里云Elasticsearch Xapck鉴权的Skywalking
可能是全网首个支持阿里云Elasticsearch Xapck鉴权的Skywalking 对Skywalking有兴趣的同学参见:年轻人的第一个APM-Skywalking 之前在搭建Skywalki ...
- 解析build.gradle文件
Gradle是一个非常先进的项目构建工具,它使用了一种基于Groovy的领域特定语言DSL来声明项目设置,摒弃了传统XML(如Ant和Maven)的各种繁琐配置 项目结构如上图: 1.最外层目录下的b ...
- python简介、第一个python程序、变量、字符编码、用户交互程序、if...else、while、for
也愿大家永葆初心-- 已识乾坤大,犹怜草木青. 一.python简介 首先,我们普及一下编程语言的基础知识.用任何编程语言来开发程序,都是为了让计算机干活,比如下载一个MP3,编写一个文档等等,而计算 ...
- 安装文件报错error while loading shared libraries: libssl.so.6
http://www.openssl.org/source/ 这里下载http://www.openssl.org/source/openssl-1.0.0r.tar.gz 安装命令为:tar -z ...
- 445. Cosine Similarity【LintCode java】
Description Cosine similarity is a measure of similarity between two vectors of an inner product spa ...
- [SHELL]查看端口,文件,服务关系的四个命令netstat,lsof,fuser,nmap
一,netstat (1)简介 netstat主要是用来打印系统网络的状态信息,当输入netstat后,输出如下: 可以看出,netstat的输出分为两个部分组成: 一个是Active Interne ...
- mongodb4简明笔记
就一数据库,掌握基本用法,其他的现学现卖就行了. 所以要把握基本套路. 创建数据库=>使用数据库=>创建集合=>使用集合=>创建文档=>使用文档 1.数据库 mongod ...
- Twitter推广消息可使品牌线下销售额增长三成
新浪科技讯 北京时间8月9日上午消息,Twitter周四宣布,该公司的推广消息(Promoted Tweet)可以让品牌的线下销售增长29%. 此外,Twitter当天还推出了一个新项目,让品牌可以追 ...
- python sys模块使用详情
python常用模块目录 sys模块提供了一系列有关Python运行环境的变量和函数.1.sys.argv可以用sys.argv获取当前正在执行的命令行参数的参数列表(list).变量解释sys.ar ...
- Python:Python的运行过程
1.Python是什么 和Java以及c#一样,Python也是一门基于虚拟机的语言.熟悉Java开发的人在命令行执行一个Java程序的过程通常如下: javac hello.java java he ...