Codeforces 1834 / Codeforces Round #879 (Div. 2)
Contest Link#
Codeforces Round #879 (Div. 2)
Problem B Maximum Strength#
题意
给定 ,求两个整数 使得 的数位差之和最大。例如 和 的数位差是 ,位数不足用前导零补齐。
题解
考场上脑子瓦特了,想的 DP:钦定 。设 分别表示高 位 是否一直处于下界, 是否处于上界,是否已经选取的位有 ,然后枚举当前位选的数,判断是否合法。
但事实上我们发现答案最大就是找到最高的位使得 的这一位 不同,然后 的这一位选 , 的这一位选 ,之后 一直选 , 一直选 。
例如:,取 最优。
Problem C Game with Reversing#
题意
Alice Bob 玩游戏。现在有两个长为 的小写字母串 ,从 Alice 开始轮流操作,Alice 可以选择串里的某个位置,改成另一个小写字母(可以和原来相同),Bob 可以选一个串进行翻转。
Alice 想要游戏尽快结束,Bob 想要游戏尽可能长。求游戏结束时总共操作了多少次。
题解
我们发现 Bob 的具体操作策略对答案没有影响,因为翻两次 和翻一次 ,翻一次 本质相同。我们只需要关心游戏结束时,Bob 究竟操作了多少次。如果操作了奇数次,Alice 必须把 改的和 的反串相同,否则必须把 和 改的相同。
我们进一步发现,Alice 的操作次数只和 和 (或其反串的差异)有关。于是分类讨论 Bob 操作次数的奇偶性,然后计算 Alice 的操作次数即可。注意有可能在 Bob 操作偶数次的情况下,Alice 需要操作的次数是一个奇数(比如 ),这个时候 Alice 必须要放空一轮,等 Bob 的第 次操作。同理另一侧也有一些特殊情况,处理一下即可。
Problem D Survey in Class#
题意
现在有 个学生, 个学科,第 个学生只会 的学科的问题。现在你作为老师,可以问一些学科的问题,当然,每一科最多问一次。初始每个学生的手高度为 。如果学生会该问题,则手的高度增加 ,否则减少 。问在所有可能的问法中,最后学生中最高的手和最低的手的高度差最大是多少。
题解
考虑钦定两个学生是最高的和最低的。发现问他们都会的和都不会的都没有意义。只需要问一个人会的,另一个人不会的,才会拉开差距。设两个人会的集合分别是 ,那么要求的就是最大的 。
考虑 怎么交 :要么和 的左端点交,要么和 的右端点交,要么完全在 内部。于是,我们只需要检查三条线段:右端点最小的,左端点最大的,长度最小的。如果其中某些线段和 没有交,那无疑是更优的。
有瓜皮考场上写了线段树。😃
Problem E MEX of LCM#
题意
给定长度为 的正整数数组 ,问最小的正整数 使得不存在任何区间的 LCM 为 。
题解
注意到 个数的 MEX 不超过 ,于是只有 LCM 小于等于 的才可能成为答案。这也说明,同一右端点的所有区间,至多只有不同的 个 LCM 可能成为答案:设这些 LCM 分别为 ,显然有 被 整除,从而 。
到这里已经可以暴力向右移动端点,然后做完了。
同时,上面的方法也证明了答案甚至是不超过 的,于是我们不用担心溢出。
Problem F Typewriter#
题意
给定一个长度为 的排列 ,初始有一个指向 的指针和一个空的缓冲区。
你可以执行以下操作:
- 如果当前指针指向的位置非空且缓冲区是空的,把这个位置上的数扔进缓冲区
- 如果缓冲区非空且当前指针指向的位置是空的,把缓冲区中的数扔到这个位置
- 如果它们都非空,交换这两个数
- 指针右移
- 指针移回
现在有 次操作,形如:
- 排列向左循环移位 步
- 排列向右循环移位 步
- 翻转排列
在第一次操作前和每次操作后,询问使用上述操作将当前排列变为 的最小指针移回 的次数。注意到这些操作不会真实发生。
题解
指针只会向右移动,显然每一次指针移回 只能让一个 的位置归位,于是答案的下界就是满足条件的 数量。同时,我们可以构造出这个下界:每次把 位置的数拿起,到 位置执行交换,指针移回 ,最后到 位置放下。为了操作冲突最小,我们按照 从小到大对于所有符合条件的 操作即可。
现在问题就是怎么维护 的位置数量。首先观察到左移和右移没有本质区别,我们只需要维护数组的开头是哪些位置的时候, 成立。不难发现这是一个连续段(也有可能是前缀 + 后缀),差分即可。
对于翻转,我们直接对于翻转后的 也维护上面的即可。考虑翻转后,左移和右移的意义恰好与翻转前相反,维护即可。
# include <bits/stdc++.h>
const int N=400010,INF=0x3f3f3f3f;
int n,q;
int T;
inline int read(void){
int res,f=1;
char c;
while((c=getchar())<'0'||c>'9')
if(c=='-')f=-1;
res=c-48;
while((c=getchar())>='0'&&c<='9')
res=res*10+c-48;
return res*f;
}
int p[N];
struct Node{
int a[N],ans[N];
inline void init(bool op){
for(int i=1;i<=n;++i) a[i]=p[op?(n-i+1):i],ans[i]=0;
for(int i=1;i<=n;++i){ // ai < i
if(a[i]<=i) ++ans[1],--ans[i-a[i]+1],++ans[i+1],--ans[n+1];
// [1,i-ai] and [i+1,n] when ai<=i; [i+1,n-(ai-i)] when ai>i;
else ++ans[i+1],--ans[n-(a[i]-i)+1];
}
for(int i=1;i<=n;++i) ans[i]+=ans[i-1];
return;
}
}sim,rev;
int main(void){
T=1;
while(T--){
n=read();
for(int i=1;i<=n;++i) p[i]=read();
q=read();
sim.init(false),rev.init(true);
int sh=0,re=1;
printf("%d\n",sim.ans[1]);
while(q--){
int op=read(); // + : left shift - : right shift
if(op==1) sh+=read()*re;
else if(op==2) sh-=read()*re;
else re*=-1;
sh=(sh%n+n)%n;
if(re==1) printf("%d\n",sim.ans[sh+1]);
else printf("%d\n",rev.ans[(n-sh)%n+1]); // reversed
}
}
return 0;
}
作者:Meatherm
出处:https://www.cnblogs.com/Meatherm/p/17492416.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
2022-06-19 【瞎口胡】后缀自动机(SAM)