第一次推出式子!
题意:
i=m∑nik
n,m≤1012,k≤2000。
题解:
众所周知 k=1 时的情况
i=1∑ni=2n(n+1)
先从证明 k=2 的情况下手。熟知公式
i=1∑ni2=6n(n+1)(2n+1)
怎么来的呢?由二项式定理
(n+1)3=n3+3n2+3n+1
即有
(n+1)3−n3=3n2+3n+1
同理有
(n+1)3−n3n3−(n−1)323−13=3n2+3n+1=3(n−1)2+3(n−1)+1⋯=3⋅12+3⋅1+1
相加有
(n+1)3−13=3i=1∑ni2+3i=1∑ni+1
展开即证。
不妨将这个过程推广到一般情况上。考虑一般二项式定理
(n+1)k+1=i=0∑k+1(ik+1)nk+1−i
拿出左式的 k+1 次项,重复上面的裂项过程
(n+1)k+1−nk+1nk+1−(n−1)k+12k+1−1k+1=i=1∑k+1(ik+1)nk+1−i=i=1∑k+1(ik+1)(n−1)k+1−i⋯=i=1∑k+1(ik+1)1k+1−i
相加有
(n+1)k+1−1k+1=i=1∑k+1(ik+1)j=1∑njk+1−i
把右式 k 次项拿出来,即得
i=1∑nik=k+11((n+1)k+1−1k+1−i=2∑k+1(ik+1)j=1∑njk+1−i)
不妨令
f(n,k)=i=1∑nik
代入上式
f(n,k)=k+11((n+1)k+1−1k+1−i=2∑k+1(ik+1)f(n,k+1−i))
即得递推式。答案为
f(n,k)−f(m−1,k)
预处理组合数,时间复杂度 O(k2)。
代码:
for (int i = 0; i <= 2001; i++) {
c[i][0] = 1;
for (int j = 1; j <= i && j <= 2001; j++)
c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % p;
}
f[0] = n;
f[1] = mul(mul(n, n + 1), Pow(2, p - 2)) % p;
g[0] = m - 1;
g[1] = mul(mul(m - 1, m), Pow(2, p - 2)) % p;
for (int i = 2; i <= k; i++) {
f[i] = (Pow(n + 1, i + 1) - 1) % p;
g[i] = (Pow(m, i + 1) - 1) % p;
for (int j = 2; j <= i + 1; j++) {
f[i] = ((f[i] - c[i + 1][j] * f[i + 1 - j] % p) % p + p) % p;
g[i] = ((g[i] - c[i + 1][j] * g[i + 1 - j] % p) % p + p) % p;
}
f[i] = mul(f[i], Pow(i + 1, p - 2));
g[i] = mul(g[i], Pow(i + 1, p - 2));
}