模拟61 题解

A. 砖块

简单模拟。

对于最后一问,算一算复杂度就可以知道开map没有任何问题,然而map真的方便很多,所以为什么不用呢。

B. 数字

容易发现末尾的0一定是被质因子2和5凑出。

并且,对于任意的$n!$,质因子2的个数不小于质因子5的个数。

简单的暴力$O(n)$做法是将$n!$中的质因子5全部除掉,将2除掉对应的个数就可以了。

注意到$10^k$可以拆为$2^k*5^k$的形式,直接求出结果是困难的。

不妨分别求出答案%$5^k$和%$2^k$的结果,使用$crt$合并得到答案。

容易发现答案%$2^k$的结果一般为0,因为$n!$中质因子2的个数远大于质因子5的个数。

所以只要求出%$5^k$的结果。

先考虑$n!$除掉质因子5之后%$5^k$的结果。

容易发现$n!$中的5可以不断被提出,转化为新的阶乘,子问题递归。

而除去5的倍数的内容可以被分组用快速幂简单算出,这个思想在扩展$lucas$求大组合数中曾多次用过。

很好的一点是,$2^x$在模$5^k$的意义下存在逆元。考试时推到了这里,但是没有想到存在逆元,于是死掉了。

可以求出$n!$中质因子5的个数$x$,将最终答案除掉$2^x$就可以了。

C. 甜圈

考试时打了吉司机线段树,也就是一个带剪枝的暴力搜索。

对于每一个区间,如果整个区间已经非法,那么直接return。

如果整个区间的值是相同的,那么共同赋值。

然而这样做似乎复杂度是有问题的。

最终得了70分,而且比暴力跑的慢。

发现一个简单的hack数据是合法和非法区间一个个交替,每次修改操作会使合法的继续合法,非法的继续非法。

解决办法是,如果线段树的左右区间一个有相同值,一个非法,那么视作该区间有相同值。

这样做复杂度似乎就正确了,然而不会分析。

正解的方法很巧妙:

将每个点都视为一个字符串,不妨对每个字符串哈希。

如果最终哈希值等于要求的哈希值,那么合法。

区间修改哈希值,直接用线段树维护乘法加法标记就可以了。

原文地址:https://www.cnblogs.com/skyh/p/11626546.html