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的更多相关文章

  1. 【题解】Atcoder ARC#90 F-Number of Digits

    Atcoder刷不动的每日一题... 首先注意到一个事实:随着 \(l, r\) 的增大,\(f(r) - f(l)\) 会越来越小.考虑暴力处理出小数据的情况,我们可以发现对于左端点 \(f(l) ...

  2. AtCoder ARC 076E - Connected?

    传送门:http://arc076.contest.atcoder.jp/tasks/arc076_c 平面上有一个R×C的网格,格点上可能写有数字1~N,每个数字出现两次.现在用一条曲线将一对相同的 ...

  3. AtCoder ARC 076D - Built?

    传送门:http://arc076.contest.atcoder.jp/tasks/arc076_b 本题是一个图论问题——Manhattan距离最小生成树(MST). 在一个平面网格上有n个格点, ...

  4. AtCoder ARC 082E - ConvexScore

    传送门:http://arc082.contest.atcoder.jp/tasks/arc082_c 本题是一个平面几何问题. 在平面直角坐标系中有一个n元点集U={Ai(xi,yi)|1≤i≤n} ...

  5. Atcoder ARC 082C/D

    C - Together 传送门:http://arc082.contest.atcoder.jp/tasks/arc082_a 本题是一个数学问题. 有一个长度为n的自然数列a[1..n],对于每一 ...

  6. 【题解】 AtCoder ARC 076 F - Exhausted? (霍尔定理+线段树)

    题面 题目大意: 给你\(m\)张椅子,排成一行,告诉你\(n\)个人,每个人可以坐的座位为\([1,l]\bigcup[r,m]\),为了让所有人坐下,问至少还要加多少张椅子. Solution: ...

  7. 【题解】Atcoder ARC#96 F-Sweet Alchemy

    首先,我们发现每一个节点所选择的次数不好直接算,因为要求一个节点被选择的次数大于等于父亲被选择的次数,且又要小于等于父亲被选择的次数 \(+D\).既然如此,考虑一棵差分的树,规定每一个节点被选择的次 ...

  8. AtCoder ARC 090 E / AtCoder 3883: Avoiding Collision

    题目传送门:ARC090E. 题意简述: 给定一张有 \(N\) 个点 \(M\) 条边的无向图.每条边有相应的边权,边权是正整数. 小 A 要从结点 \(S\) 走到结点 \(T\) ,而小 B 则 ...

  9. 【题解】Atcoder ARC#67 F-Yakiniku Restaurants

    觉得我的解法好简单,好优美啊QAQ 首先想想暴力怎么办.暴力的话,我们就枚举左右端点,然后显然每张购物券都取最大的值.这样的复杂度是 \(O(n ^{2} m)\) 的.但是这样明显能够感觉到我们重复 ...

  10. 【题解】Atcoder ARC#85 E-MUL

    ……没啥可说的.最大权闭合子图,跑下dinic就好了…… #include <bits/stdc++.h> using namespace std; #define maxn 500000 ...

随机推荐

  1. Java 泛型通配符 T,E,K,V,?

    Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许开发者在编译时检测到非法的类型. 泛型的本质是参数化类型,也就是说所操作的数据类型被 ...

  2. oracle函数listagg使用

    作用 可以实现将多列记录聚合为一列记录,实现数据的压缩 语法结构 listagg(measure_expr,delimiter) within group ( order by order_by_cl ...

  3. vue项目在ie浏览器下报语法错误

    错误如下: 1.用vue 写的项目最多可以兼容到IE9 及以上版本 2.使用babel-polyfill做兼容npm install babel-polyfill --save-dev 安装之后如果发 ...

  4. vue为什么要设计成异步队列渲染

    异步队列渲染 上一篇文章是在vue2.0 中通过Object.defineProperty去拦截并监听数据变化的响应式原理,这篇文章将会沿着图谱继续深入探索,在依赖被通知变化了之后,会触发vue当中的 ...

  5. Layui 的内置jquery 版本

    //layui-v2.4.5 的内置jquery 版本. console.log(layui.$.fn.jquery);//=> 1.12.3 可以使用内置jq的方法: 方法一: layui.u ...

  6. .net Core WebApi使用AutoFac

    1.在要添加的项目中选中 依赖项->右键->管理NuGet程序包(N) 2.在NuGet包管理器中输入Autofac,安装选中文件 3.在项目中找到Program.cs文件,添加如下代码 ...

  7. CSS基础 CSS的三大特性以及选择器优先级计算方法

    1.子元素默认会继承父元素的样式,但不是所有的元素都有继承 常见的继承父元素特点的元素有: 1.color 2.font-sytle.font-weight.font-size.font-family ...

  8. Hadoop 之 高可用不自动切换(ssh密钥无效 Caused by: com.jcraft.jsch.JSchException: invalid privatekey )

    案例 在安装hadoop ha之后,验证HDFS高可用时,怎么都不能实现自动切换.查看zkfc日志发现错误信息如下: WARN org.apache.hadoop.ha.SshFenceByTcpPo ...

  9. 初识python: flush 实现进度条打印

    通过flush(强制刷新)实现,类似进度条打印: #!/user/bin env python # author:Simple-Sir # time:20180918 #打印进度条 import sy ...

  10. Flask_Flask-Script脚本扩展的使用(八)

    Flask-Script扩展包提供向Flask插入外部脚本的功能,包括运行一个开发用的服务器,一个定制的Python shell,设置数据库的脚本,cronjobs,及其他运行在web应用之外的命令行 ...