Atcoder ARC-060
ARC060(2020.7.8)
A
背包板子
B
首先感觉这个东西应该不能直接 \(O(1)\) 算出来,那么复杂度应该就是 \(O(\log n), O(\sqrt{n}), O(\sqrt{n} \log n)\) 之类的,看数据范围可以猜到应该不是 \(O(\log n)\) 的(其实是不知道怎么做)。于是按照套路我们考虑根号分治,可以考虑枚举这个 \(b\),那么对于 \(b \le \sqrt{n}\) 的部分,直接枚举即可,再 \(O(\log n)\) 判断。然后我们可以发现对于 \(b > \sqrt{n}\) 的部分,因为 \(b ^ 2 > n\) 那么 \(n\) 在 \(b\) 进制下最多只有两位,那么不妨设 \(pb + q = n\) 则 \(p + q = s\) 两式相减可得,\(p(b - 1) = n - s\),则 \(b - 1 \mid n - s\) 于是可以考虑枚举 \(n - s\) 小于 \(\sqrt{n - s}\) 的约数 \(d\) 那么 \(b - 1 = \frac{n - s}{d}\) 这一部分的复杂度同样是 \(O(\sqrt{n} \log n)\) 的,因此总复杂度 \(O(\sqrt{n} \log n)\).
C
可以发现我们可以预处理出每个点再一天内往后最远能到达的点,于是问题就变成问从一个点最少往后跳几次能跳过另一个点,那么我们可以直接分块处理,预处理出一个点走出块内第一个点需要的最短跳跃次数,于是查询只需要跳块即可。那么复杂度就可以做到 \(O(n \sqrt{n})\) 了,那么还有没有更优秀的做法呢?实际上是有的,可以考虑倍增,那么类似于求 \(\rm LCA\) 的倍增方式跳到下标小于另一个点的第一个点,次数 \(+1\) 即是答案。
D
首先有一些特殊情况,首先如果原串是不循环的,那么答案就是 \(1, 1\),其次如果原串中的每个元素都相同,那么答案就是 \(n, 1\),对于剩下的情况,我认为将原循环串去掉最后一位剩下的串不可能是一个循环串,于是我大胆地猜测第一问的答案是 \(2\),结果还猜对了。下面是一个关于字符串循环节很关键的一个性质:
给定两个正整数 \(p, q\) 如果一个长度不小于 \(p + q - \gcd(p, q)\) 的串 \(S\) 中存在长度为 \(p, q\) 的循环节,那么 \(\gcd(p, q)\) 也是 \(S\) 的循环节。
考虑将循环的意义用数学语言表达下来,不难发现对于 \(\forall i \in [1, n]\) 有 \(S_i = S_{i + p} = S_{i + q} = S_{i + px + qy}\),根据裴蜀定理考虑到 \(px + qy = \gcd(p, q)\) 是一定有解的,那么就会有 \(S_i = S_{i + \gcd(p, q)}\) 也就意味着 \(\gcd(p, q)\) 也是一个循环节。
那么我们将原串去掉最后一位之后假设剩下的串最小循环节长度为 \(x\),原串最小循环节长度为 \(y\),因为 \(\gcd(n - 1, n) = 1\) 因此 \(n - 1, n\) 不会包含相同约数,因此 \(\gcd(x, y) = 1\),那么根据上面的性质,将原串继续按照循环节延长,那么 \(1 \sim x \times y\) 这一段子串就一定会含有 \(x, y\) 两种循环节,那么 \(gcd(x, y) = 1\) 也会是一种循环节,因此原串中每一个字符都将相等与条件矛盾。
那么下面我们就只需要枚举中间的断点,判断左右是否都是不循环的即可。接下来又是一个非常重要的结论,一个字符串存在循环节的充要条件是 \(\exist x \mid n, S_{1, n - x} = S_{x + 1, n}\)

首先假设 \(S_{1, x}\) 是上图中的绿色部分,其他颜色分别是长度为 \(x\) 的块,因为 \(S_{1, n - x} = S_{x + 1, n}\) 那么相同颜色块应该相同,又根据在原串中的位置可以得到绿色块和黄色块相同,同理又可以得到黄色块和红色块相同,以此类推可以得到原串是个循环串。
得到循环串的判定条件后我们发现需要枚举这个长度 \(x\),又因为 \(x \mid n\) 那么我们可以枚举 \(n\) 的约数,事实上因为我们需要知道的是前缀是否是循环的,那么第一个循环节都会是从 \(1\) 开始的,那么我们枚举第一个循环节的长度,那么能以该长度作为循环节的只有其倍数,那么我们再枚举一下其倍数 \(\rm Hash\) 一下就可以 \(O(1)\) 判断了,后缀也是类似的。那么最终统计答案就非常简单了。
可以发现上面那个做法的复杂度是 \(O(n \ln n)\) 的,那么能不能做到 \(O(n)\) 呢?事实上是可以的,需要使用到 \(kmp\) 的性质。
首先我们可以将判断是否循环的条件改成 \(n - nxt_{n} \mid n\)。首先我们可以知道如果 \(n - nxt_{n} \mid n\) 那么是一定有循环节的,类似上面的证明。下面来证明对于 \(n - nxt_{n} \nmid n\) 的情况不存在循环节。
首先考虑 \(nxt\) 数组的定义,不难发现有 \(S_{1, nxt_n} = S_{n - nxt_n + 1, n}\),那么类似于第一种做法循环节的证明方法,可以发现 \(S_{1, n - nxt_n}\) 也可以在原串中循环只是不能刚好循环完毕,即最后一次循环只能出现部分。我们称这种循环节为伪循环节。
首先令 \(x = n - nxt_n\),假设存在一个长度为 \(len\) 的循环节,显然 \(len \ne x\)。首先如果 \(len < x\),那么显然 \(nxt_n\) 可以变大,矛盾。如果 \(x \mid len\) 既然 \(len\) 都能循环那么 \(x\) 一样能循环,矛盾。对于 \(x \nmid len\) 的情况,因为 \(x \nmid len\) 那么一定存在一个伪循环节会跨过第一个循环节和第二个循环节,假设这个伪循环节是第 \(k\) 个,那么 \(S_{len + 1, len + x} = S_{1, x} = S_{k \times x + 1, (k + 1) \times x}\) 可以发现 \(S_{len + 1, len + x}, S_{k \times x + 1, (k + 1) \times x}\) 重叠了一段区间且长度相同,那么 \(S_{len + 1, k \times x}\) 就可以作为一段新的伪循环节,且长度小于 \(x\),那么 \(nxt_n\) 一样可以变大,矛盾。
那么我们 \(kmp\) 可以求出每个位置的 \(nxt\) 值,前缀后缀判断是可以 \(O(1)\) 做到的,因此总复杂度 \(O(n)\).
实际上循环节还有一个很奇妙的性质,即所有循环节长度都是最小循环节长度的倍数。假设存在两个个长度为 \(p, q(\gcd(p, q) \ne p)\) 的循环节,\(p\) 为长度最小的循环节。那么显然有 \(\gcd(p, q) < p\),根据最开始的那条性质,\(\gcd(p, q)\) 也是一个循环节,那么最小循环节的长度就会是 \(\gcd(p, q)\) 而不是 \(p\),矛盾。
Atcoder ARC-060的更多相关文章
- 【题解】Atcoder ARC#90 F-Number of Digits
Atcoder刷不动的每日一题... 首先注意到一个事实:随着 \(l, r\) 的增大,\(f(r) - f(l)\) 会越来越小.考虑暴力处理出小数据的情况,我们可以发现对于左端点 \(f(l) ...
- AtCoder ARC 076E - Connected?
传送门:http://arc076.contest.atcoder.jp/tasks/arc076_c 平面上有一个R×C的网格,格点上可能写有数字1~N,每个数字出现两次.现在用一条曲线将一对相同的 ...
- AtCoder ARC 076D - Built?
传送门:http://arc076.contest.atcoder.jp/tasks/arc076_b 本题是一个图论问题——Manhattan距离最小生成树(MST). 在一个平面网格上有n个格点, ...
- AtCoder ARC 082E - ConvexScore
传送门:http://arc082.contest.atcoder.jp/tasks/arc082_c 本题是一个平面几何问题. 在平面直角坐标系中有一个n元点集U={Ai(xi,yi)|1≤i≤n} ...
- Atcoder ARC 082C/D
C - Together 传送门:http://arc082.contest.atcoder.jp/tasks/arc082_a 本题是一个数学问题. 有一个长度为n的自然数列a[1..n],对于每一 ...
- 【题解】 AtCoder ARC 076 F - Exhausted? (霍尔定理+线段树)
题面 题目大意: 给你\(m\)张椅子,排成一行,告诉你\(n\)个人,每个人可以坐的座位为\([1,l]\bigcup[r,m]\),为了让所有人坐下,问至少还要加多少张椅子. Solution: ...
- 【题解】Atcoder ARC#96 F-Sweet Alchemy
首先,我们发现每一个节点所选择的次数不好直接算,因为要求一个节点被选择的次数大于等于父亲被选择的次数,且又要小于等于父亲被选择的次数 \(+D\).既然如此,考虑一棵差分的树,规定每一个节点被选择的次 ...
- AtCoder ARC 090 E / AtCoder 3883: Avoiding Collision
题目传送门:ARC090E. 题意简述: 给定一张有 \(N\) 个点 \(M\) 条边的无向图.每条边有相应的边权,边权是正整数. 小 A 要从结点 \(S\) 走到结点 \(T\) ,而小 B 则 ...
- 【题解】Atcoder ARC#67 F-Yakiniku Restaurants
觉得我的解法好简单,好优美啊QAQ 首先想想暴力怎么办.暴力的话,我们就枚举左右端点,然后显然每张购物券都取最大的值.这样的复杂度是 \(O(n ^{2} m)\) 的.但是这样明显能够感觉到我们重复 ...
- 【题解】Atcoder ARC#85 E-MUL
……没啥可说的.最大权闭合子图,跑下dinic就好了…… #include <bits/stdc++.h> using namespace std; #define maxn 500000 ...
随机推荐
- Notepad++汉化教程
Notepad++汉化方法总结 Notepad++系统只带了中文语言包,不需要像其他软件一样破解 打开Notepad++(通过文本文件右键选择以Notepad++打开或者找到Notepad++的快捷方 ...
- springboot单元测试为什么排除junit-vintage-engine
https://blog.csdn.net/Ber_Bai/article/details/117001443 如果不排除,就需要使用@RunWith注解? 25-springboot整合单元测试指定 ...
- PHP 的扩展类型及安装方式
扩展类型 底层扩展(基于C语言): PECL 上层扩展(基于PHP 语言): PEAR Composer PECL # 查找扩展 $ pecl search extname # 安装扩展 $ pecl ...
- 适配器模式(pthon)
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # adapter_pattern.py # 适配器模式 class Adaptee: def reque ...
- k8s 理解Service工作原理
什么是service? Service是将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法. 简单来说K8s提供了service对象来访问pod.我们在<k8s网络模型与集群通信> ...
- 硬核 - Java 随机数相关 API 的演进与思考(上)
本系列将 Java 17 之前的随机数 API 以及 Java 17 之后的统一 API 都做了比较详细的说明,并且将随机数的特性以及实现思路也做了一些简单的分析,帮助大家明白为何会有这么多的随机数算 ...
- Lucene8.5.x全文检索工具
本文的资源展示: hotword:是热词的文本,比如不是词语的中文,但是是什么人名或者公司名称的词语,需要分词成一个词语的将需要的加入hotword.dic stopword:无意义的词放入的词典,或 ...
- session反序列化
先来了解一下关于session的一些基础知识 什么是session?在计算机中,尤其是在网络应用中,称为"会话控制".Session 对象存储特定用户会话所需的属性及配置信息.这样 ...
- x86架构应用如何向Arm架构低成本迁移
曾几何时,无论是在服务器还是个人电脑,CPU芯片领域一直是 Intel 独占鳌头,旗下的 X86_64 架构被广泛采用.然而王权没有永恒,近年来 Arm64 架构异军突起,服务器端有华为鲲鹏920高性 ...
- 【Java】toString
toString 当我们输出一个对象的引用时,实际上就是调用当前对象的toString() Object类中toString()的定义: public String toString() { retu ...