省选模拟37 题解

点点圈 提交于 2020-03-04 00:03:21

A. Alchemy

考虑递归挪动这个塔的过程。

然后发现有一些递归是没有必要的。

通过初始状态可以判断递归的前半部分或后半部分是没有必要的。

直接统计不递归的部分的贡献,然后递归另一部分就好了。

这样的复杂度应该可以做到线性。

 

B. Algebra

要统计这个答案无非两个办法。找到 $n$,判断在两个进制下的和是否相等。

找到两个进制下相等的数,然后取交集找到 $n$。

采用后一种办法。

考虑首先写一个函数 $next(n,k,s)$ 表示 $\geq n$ 的 $k$ 进制下总和为 $s$ 的最小的数字。

这个函数写一个类似数位 dp 的东西就可以 $O(log n)$ 求出来。

然后设 $g_s$ 表示 $s$ 的答案至少为 $g_s$。

那么每次取出最小的 $g_s$,通过 $next(g_s,a,s),next(g_s,b,s)$ 的取值,可以判断是否找到答案。

如果没有找到答案,那么更新 $g_s$ 。

 

C. Anarchy

暴力的做法是枚举$x,y$,然后计算两点之间的距离。

然而这个算法不是很好优化,考虑现在枚举 $x$ 和 $y-x$。

也就是说枚举爆炸点和爆炸向量,然后可以更新对应的 $y$。

这样的话问题可以写成一个卷积的形式 $ans_y=\sum \limits_{i \oplus j=y}a_i*dis_j$。

$\oplus$ 操作即对位相加在模意义下相等。

考虑构造一个 $DFT$ ,这个 $DFT$ 实际上就是按照维度依次做一下快速傅里叶变换。

所以问题是怎么做任意长度 $FFT$。

要求的是 $b_i=\sum \limits_{j=0}^{n-1}a_i*w_n^{ij}$,这个 $i*j$ 就很恶心。

一个处理这个的套路是把 $i*j$ 展开为 $\dfrac{(i+j)^2-i^2-j^2}{2}$,于是直接做 $FFT$ 卷积就完事了。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!