图计数

来源:互联网 发布:统计学数据分析报告 编辑:程序博客网 时间:2024/06/06 02:26

题意

给定n,m,求mNmodP。其中,P=999999599N为将n进行整数拆分的方案数,即将n表示成若干个正整数之和的方案数。

n,m200000

Time  Limits:3000ms
Memory  Limits:256M

分析

根据费马小定理,mN=mNmod(P1),这个可用快速幂算。我们的问题就是如何求Nmod(P1)

我们先想O(N2)的算法。因为每个正整数都能使用若干次,那么这就是一个完全背包问题。但是本题中此算法的复杂度显然不可接受。

我们把正整数以N分界。
那么对于小于等于N的正整数,我们直接完全背包,求出用它们组成和为i的方案数,记为f[i]。这里的时间复杂度是O(NN)
对于大于N的正整数,可以发现,我们最多只会选择N个。记k=N,我们考虑这样一个方程:
g[i][j]为已经选了i个数,它们的和为j的方案数。
转移:g[i][j]=g[i1][jk]+g[i][ji]

这个方程是什么意思呢?
我们把每个选择的数xi都看成由k加上xik1达到的。那么一种选择数的方案{xn}序列,把它们从大到小排序,我们可以在加入第一个k后,将第一个数加上(x1x2)1;然后加入第二个k,把前两个数加上(x2x3)1;加入第三个k,把前三个数加上(x3x4)1 ……这样做到最后,我们把所有数加上(xnk)1,我们就能得到这个方案。

这样,我们就同样能以O(NN)的时间复杂度求出g,然后将fg合并求出组成和为n的方案数就行了。

注意:求fg要滚动数组。

0 0
原创粉丝点击