Codeforces 893E - Counting Arrays
Table of Contents
题面
对于正整数 和 ,求有多少种长度为 的序列,其元素的乘积为 。序列中允许出现负数,对于两个序列 和 只要存在 就视作两个不同序列。答案对 取模。
数据范围:
一组数据有 次询问,
组合数学
思路
首先,我们对 分解质因数:
同时,我们知道序列中的任意一个值 一定可以表示为如下形式:
现在我们先暂且不考虑负数的情况。我们把质因子视作”小球”,序列中的每一个元素视为”箱子”。由此我们可以把问题转换为经典的”球放箱子”问题:现有 类小球,第 类小球有 个,同时有 个箱子,箱子可以为空,试问把所有小球放到箱子里有多少种放法。
对于第 类小球,一共有 个,同时一个箱子可以放多个。这等效于一共有 个箱子且每个箱子最多放一个小球。因此摆放种数为:
根据乘法原理,所有小球的总摆放种数为:
接下来,我们来考虑负数。显然,在序列中, 个数的正负可以是任意的,而乘积的正负可以由剩下的那一个数来决定。所以,总拜访种数为:
实现
这道题思路是可以说是非常简单,但是看看数据范围就知道在实现上需要运用一些技巧。
首先,在对 分解质因数前需要先线性筛素数,分解质因数时应尽量”剪枝”。
在求组合数时复杂度应做到 ,因此需要预处理 及其对于 逆元。
最后,还要预处理 的幂。
另外在做这道题的过程中顺便学到了一种线性预处理逆元的算法,但这道题用不到。为了试试这种算法,第一份参考代码中使用了这一算法来预处理逆元。
%%%
- miskcoo - [数论] 线性求所有逆元的方法