Interesting Problems
[WC2015] 未来程序
给定 \(10\) 个程序及其输入数据,在本地跑出其对应的输出数据。
Task 1
执行若干次加法,本质上是乘法,用 __int128 进行即可,或者写个类似快速幂的东西求都可以。
期望运行时间 \(\texttt{1s}\)。
Task 2
执行若干次赋值,注意到每一次循环会重新用 \(a,b,c\) 进行运算得到新的 \(a',b',c'\),观察得到其矩阵递推式为:
矩阵快速幂即可,期望运行时间 \(\texttt{1s}\)。
还是个倒着的杨辉三角。
Task 3
求 \(n\) 以内自然数的 \(0,1,2,3,4\) 次方和,特别的,\(0^0=1\)。
直接套公式即可:
高精度交给 Python,期望运行时间 \(\texttt{1s}\)。
Task 4
给定一个 01 矩阵,求:
- 有多少个有序坐标二元组,满足两个位置上的值都是 \(1\)。
- 对每个为 \(1\) 的位置求最近的 \(0\) 的位置,距离为曼哈顿距离。
子问题 \(1\):记 \(x\) 为 \(1\) 的个数,则答案为 \(x(x-1)\)。
子问题 \(2\):写一个 DP 即可,四个方向都做一遍。
期望运行时间 \(\texttt{1s}\)。
Task 5
给定一个 01 矩阵,求有多少个全 1 的子矩阵。
经典单调栈问题,记以当前点为右下角的矩阵数量。
期望运行时间 \(\texttt{1s}\)。
Task 6
给定 \(a,b,c\),每次将 \(t\) 改为 \(at^2+b\) 自然溢出后对 \(c\) 取余,求 \(n\) 次操作后的结果。
没什么规律,不妨找循环节,采用 Floyd 判环即可。
期望运行时间 \(\texttt{90s}\)。
Task 7
求解 \(16\times 16\) 的数独。
加两个优化:只尝试填写可填写的数字,优先填写可能性较少的位置。
期望运行时间 \(\texttt{10s}\)。
Task 8
七重循环枚举 \(a,b,c,d,e,f,g\),对十种不同的偏序关系组计数,答案对质数 \(1234567891\) 取余。
断言答案会是一个关于 \(n\) 的不超过 \(10\) 次的多项式,拉格朗日插值即可。
期望运行时间 \(\texttt{1s}\)。
Task 9
求十个字符串,已知 MD5。
第一问与第二问:只枚举数字,长度限制在 \(6\) 即可。
第三问:找到当年讲课的老师,把名字一个一个试一遍。
第四问:长度限制在 \(3\) 即可。
第五问至第九问:先把长度控制在 \(5\sim 6\) 然后跑。
第十问:不好推,有了解的人就会知道是什么。
名言:We hold these truths to be self-evident. 来源于美国独立宣言。
期望运行时间 \(\texttt{2s}\)。
Task 10
给定大量函数的嵌套关系,求底层程序的执行次数。
发现函数调用呈 DAG 样,写个程序把 DAG 建出来然后简单跑个 DP。
期望运行时间 \(\texttt{1s}\)。
[十二省联考 2019] 骗分过样例
你的目标是:给定 \(16\) 组输入/输出数据,每个测试点的功能编号给出,写一个程序从对应输入跑出对应输出。
总输出量极大,程序源文件大小 \(\leq 100\text{KiB}\)。
Ready? Go!
Code: 1_998244353 (12pts)
通过一些小小的观察我们可以大胆猜测,输入 \(x\) 的输出即为 \(19^x \bmod 998244353\)。
输入数据大的时候运用费马小定理,在快读时将 \(x\) 变小即可。
Code: 1? (7pts)
通过一些小小的观察我们依旧可以大胆猜测,输入 \(x\) 的输出即为 \(19^x\) ,但是模数不知道。
再看一眼输出文件,值域都非常小,看了几个都没有大于 \(1140000\) 的,先果断猜一手 \(1145140+x(0\leq x\leq 9)\) 形式的数。
发现 \(1145141\) 就是模数。
其实也可以枚举。
Code: 1?+ (9pts)
通过一些小小的观察我们还是可以大胆猜测,输入 \(x\) 的输出即为 \(19^x\) ,但是模数不知道。
值域比较大,不好处理。
但是离线掉输入文件之后发现有两个询问的很大的 \(x\) 相差为 \(2\),也就是说答案是 \(361\) 倍,那么模数肯定是 \(361x-y\) 的约数,从大往小枚举判断即可。
Code: 1wa_998244353 (13pts)
通过一些小小的观察我们可以继续大胆猜测,输入 \(x\) 的输出即为 \(19^x\) ,但是溢出了。
经过对快速幂的各种魔改发现,应该不是快速幂形式。
然后再试:发现直接递推答案然后再 int 范围内溢出再模非常合理。
问题是这个不好通项或快速递推,考虑其它方法,一个比较简单的方法是判断循环节,写个程序算一下发现循环节长度不到 \(10^5\),找循环节然后计算即可。
Code: 2p (18pts)
通过对 p 的分布进行观察,并结合英文术语,猜测是 prime,即 \([l,r]\) 内素数的分布。
Miller-Rabin 模板。
Code: 2u (20pts)
通过对输出的符号 +-0 进行观察,并结合英文术语,猜测是 mu,即 \([l,r]\) 内的 \(\mu\) 函数值。
开始上强度了,我们如何计算 \(\mu\) 呢?
有一个经典问题是求 \([l,r]\) 内的素数 \(r\leq 10^{12}, r-l+1\leq 10^6\),预处理出 \(\sqrt{r}\) 以内的素数然后埃筛标记。
求 \(\mu\) 函数同理,但是可以做到更高数量级,我们筛出 \(\sqrt[3]{r}\) 以内的素数然后埃筛跑贡献,并将所有数字除去这些素数。
不为 \(1\) 的数字会满足如下形式其一:
- \(p\) 表示是一个素数,这会使得 \(\mu\) 乘上 \(-1\)。
- \(pq\) 表示两个素数的乘积,这不会改变 \(\mu\) 值。
- \(p^2\) 表示一个素数的平方,这会使得 \(\mu\) 变为 \(0\)。
通过 Miller-Rabin 与二分开根,上述三种情况可以判定。
卡常小技巧:
- 对每个数字除素数时只需要除最多 \(2\) 次。
- 除去小素数后不为 \(1\) 的只需考虑 \(\mu\ne 0\) 的情况。
Code: 2g (12pts)
观察输入数据以及数感,可以发现是 \([l,r]\) 内 \(p\) 的原根的分布。
当 \(p=998244353\) 时区间都不大,可以用原根判定定理直接判。
当 \(p=13123111\) 时需要通过找最小原根,然后用顶标与 \(\varphi(p)\) 互质的原根幂次生成所有原根。
Code: 2g+ (9pts)
\(p=998244353\) 不再说明,问题是 \(p\) 不知道的怎么办?
猜测 \(p\) 会离 \([10^9,2\times 10^9]\) 的中点比较近,从 \(1.5\times 10^9\) 开始枚举素数 \(p\),并枚举前 \(20\) 个是否是原根与答案比较即可。
\(8\) 个 Case 已经全部完成,So congratulate to us.

浙公网安备 33010602011771号