君と彼女の恋

来源:互联网 发布:vs2010 编译php扩展 编辑:程序博客网 时间:2024/05/01 12:32

题目大意及模型转换:

找出有多少个集合满足以下要求:
1、所有数模M两两不同
2、所有数之和为N
N<=10^18,M<=100。结果很大,要求模一个大质数。
集合包含同样的数,而顺序不同视为不同集合。

小思路:

为了满足约束1,可以先选出一些余数(0~M-1),然后不断给其中的余数加M(这样显然这个数模M不会改变),直至达到N。也就是说,题目转换为选一些余数,使余数之和与N对模M同余,并统计将这些余数,每次不断加M,直至达到N的方案数。

DP:

显然可以想到,余数之和最大为M^2(实际为M*(M-1)/2,这里为了叙述方便)。那么我们发现,还要记录个数(因为如果已知余数和为i,还要知道用多少个构成了i,才能统计方案数)。那么个数最大为M。可以设f[i,j]表示选了j个余数使其和为i的方案数。那么显然可以写出转移式f[i,j]=∑f[i-k,j-1]。枚举k需要O(M),枚举状态需要O(M^3)。可以得知此DP是O(M^4)的。

统计答案:

现在,我们假设Q=N mod M,P=N div M。我们可以枚举一个j,要求余数和为Q+j*M,那么可以得知这样我们还需要反复做以下操作P-j次:不断给其中一个余数加M。注意了,假设用i个余数组成,那么方案并不是i^(P-j)的,因为会有重复。这时我们考虑这样一个组合数问题。

隔板放球:

考虑这样一个问题,在N个盒子里放入M个球的方案数。我们可以把N个盒子看作N+1个隔板,那么除去两边没有用的隔板一共有N-1个隔板,放入M个球后,如果把球与隔板统称为“东西”,那么一共有N+M-1个“东西”,其中有N-1个“东西”是隔板。所以,我们可以得出方案数为CN1N+M1

求解组合数:

注意到N+M-1会变得很大,我们需要快速求解组合数。以下有两种方法

方法一

CXY=Y!X!(YX)!=(Y1)!(X1)!(YX)!Y/X=CX1Y1Y/X
因此我们可以不断把弄下去直至变为C0YX,然后再推回来,复杂度为O(X),可以得出X<=M。

方法二

CXY=Y!X!(YX)!=Yi=YX+1iX!
那么就可以用O(X)的方法算出。

注意:

由于是排列,所以还要乘上i的阶乘(i表示为选择了i个余数)。计算组合数用到了除法,我们应该改为乘以它的逆元。因为模的是大质数,所以满足费马小定理前提,那么a*b同余a/b’。其中b*b’=1(mod p),且b’=b^(p-2) mod p。
由于每个余数只能选一次,是01背包问题,所以枚举时次数与和都得倒序,而且转移用到的k放在第一层。

0 0
原创粉丝点击