Tsawke's Exam (Standard) Solution

T1 Tsawke的学习资料

原题是 Luogu-P3052 [USACO12MAR]Cows in a Skyscraper G,改动不多。

此题方法非常多。

10pts

暴力跑一下即可,没什么可说的。

100pts

模拟退火

观察发现 n 很小,且对于一个确定的序列,O(n2) 的 DP 很显然,令 dp(i) 表示前 i 个数据至少需要多少个硬盘,预处理前缀和 sum(i),有:

dp(i)=min(dp(i),dp(j)+1)(j[0,i1]sum(i)sum(j)m)

于是考虑在模拟退火时随机两个点并交换,然后进行一次 DP,可以顺便再加个卡时。

然后发现过不了所有点,所以考虑对数据进行一些微小扰动,于是考虑到将 m 变为 m×1.05,可以通过。

搜索 + 剪枝

就是朴素搜索,然后该 return 的时候 return,考虑为了让它尽快 return,降序排序一下,然后就过了

状压 DP

挺显然的,是状压可能比较好看出来,但是状态设计应该需要点思考,可以去 Luogu 看看。

总结一下

emm 大概这样,挺水的,个人感觉搜索应该是最好想的,模拟退火是最有意思的(尤其这个随机扰动也太离谱了),应该都能切吧?

Code(模拟退火)

T2 这tm也是传统题???

十分奇怪的一道题,不过其中涉及到的很多知识点却又是很实用的。

题意描述的已经很清楚了,这里对于每类点分别写一个 namespace 并分别讲解。

Default

这些是本题很多地方需要用到的一些函数,这里我把它们封装到一起:

下面对这些函数的作用进行简单说明:

随机数生成器。

标准的快读模板。

读入一些特别长的数,并在读入过程中取模。

快速幂模板。

快速乘模板,用 __int128_t 实现。

用于快速判定是否为素数,关于 Miller Rabin

Case 1~3

简单观察发现输入为 0,1,2,3,

输出为 1,19,361,6859,

显然为 190,191,192,193,

所以显然这个功能即为输入 x 输出 19x

然后观察文件名发现其中有 998244353 字段,十分显然就是对其取模,即求的是 19xmod998244353

对于前两个点简单的快速幂就能过,而对于第三个点发现 x 很大,所以需要用到欧拉定理:

p 为素数,则有 ap11(modp)

简单转化一下,令 19xmod998244353=ξ 则有:

19p11(modp)19x19xmodp1(modp)ξ19xmodp1(modp)

所以对于这三个点丢可以直接输出 19xmodp1mod998244353

同时发现 x 超过 long long 了,于是我们需要在读入的时候边读入边取模。

Case 4

观察文件名发现,区别只是模数变成了 ?,于是这也很显然,我们需要确定模数。

观察样例,我们发现以下几个性质:

于是写出枚举找素数的程序:

跑一下就可以得到素数为 1145141

Case 5

既然是升级版肯定不会让你这么简单枚举出来模数的

有一个很人类智慧的枚举方法,对于整个输入输出,我们要找到一对最接近的 x,yx<y,且对于答案有 ansx>ansy

这时简单想一下就会发现可以通过 x 的答案推出来没有取模完全的 y 的答案,也就是:ansx×19yxansy(modp)

或者写成:ansx×19yxmodp=ansy

所以显然这个时候我们需要枚举的模数就只可能是 ansx×19yxansy 的因数。

思路大概这样,实现就不写了,只需要注意两个点:

总之最后得出来的结果应该是:

模数是 719200885258981741674 的因数,模数下界是 5211500658258874319,最终计算得出模数为 5211600617818708273

Case 6~7

观察文件名发现序号没变,那么求的东西不变,然后观察文件名里有 wa,输出的答案里有负数,又联想到提示里的内容,所以显然这个是因为 int 溢出了所以变成负数。

然后我们感性理解一下,模意义下的很多模数都是一个群,从群的角度感性理解一下这个溢出应该也会有周期性,所以我们可以通过 map < int, int > 来找第一个重复出现的数,也就是周期。

大概的实现是这样:

Case 8~10

序号变为 2,所以显然要实现的功能改变了,观察文件名 p 显然代表着 Prime,简单看一下样例就能明白要实现的是对于 [l,r] 的数,质数输出 p,合数输出 .,简单用 Miller-Rabin 判一下即可。

Case 11~13

观察文件名 u 显然是求莫比乌斯函数,对于第一个点显然打个线性筛就行,具体看这里

第二第三个点可以理解为求任意区间内的莫比乌斯函数,可以考虑把值域分一下,预处理出 (1018)13=106 以内的莫比乌斯函数和质数,然后在要求的区间内筛一下,把每个数中的 106 以内的质因子全部除下去,然后在除的时候注意维护莫比乌斯函数,特判一下如果有平方因子变成零就行,相信你们都会

然后显然对于区间内最后剩下的数一定是一下几个情况:

这里如果 μ 已经为 0 或剩下的数已经为 1 了则可以不用讨论,是个小剪枝。

不过这题 Luogu 上卡常很离谱, 12,13 很难卡过,有一个很不严谨的卡常,通过面向数据剪枝我们可以发现如果把求莫比乌斯函数时候的 Miller-Rabin 测试次数设置为 1,只测试底数为 2刚好可以把数据卡过不影响正确性,于是可以卡常过 Luogu,在 LOJ 上评测机比较快可以不用考虑这一点。

Case 14~16

观察文件名 g 显然是要求区间内的数是否为原根。对于第一个点模数全为 998244353,区间不是很大,直接把 ϕ(998244353) 质因数分解然后对于区间内每一个数跑一遍暴力验证即可。即:

对于其所有质因数 frac(i)gϕ(MOD)frac(i)1

对于第二个点多了一个 13123111,且区间较大,不能暴力跑,于是考虑有如下性质:

对于原根 ggx(modMOD) 为原根当且仅当 xϕ(MOD),这个 x 似乎叫做指标。

可以考虑把其分解质因数,标记所有其质因数的区间内的倍数,也就是筛一下,最终所有没有标记的数可以表示为 gx 的即为原根。

然后对于最后一个点,和之前的思路一样,显然模数是质数,把模数枚举一下,然后选二十个左右的数据,随便选一个质因子验证一下,很快就能跑出来模数为 1515343657

AC Code

T3 快打开GeoGebra

对于每个数据各种人类智慧的毒瘤题。。。

原题:LG-P5600 【XR-4】尺规作图

可以去参考一下 Luogu 的题解,咕咕咕。