1. 程式人生 > >【BZOJ3157】【BZOJ3516】【51nod1229】國王奇遇記 & 數列求和V2(自然數冪和,遞推)

【BZOJ3157】【BZOJ3516】【51nod1229】國王奇遇記 & 數列求和V2(自然數冪和,遞推)

Description

i=1nikri

Solution

r=1時,就是個裸的自然數冪和問題。

如果r1,類似於求自然數冪和時的遞推做法,設S(k)=i=1nikri
那麼rS(k)=i=1nikri+1=i=1n+1(i1)kri+1
所以有:

(r1)S(k)=nkrn+1+i=1n[(i1)kik]ri=nkrn+1+i=1nj=0k1(1)kj(kj)ijri=nkrn+1+j=0k1(1)kj(kj)i=1nijri=nkrn+1+j=0k1(1)kj(kj)S(j)
直接遞推即可。

Code

inline LL Pow(LL a, LL b)
{
    LL Ans = 1;
    for (a %= Mod ; b; b >>= 1, (a *= a) %= Mod) if (b & 1
) (Ans *= a) %= Mod; return Ans; } inline LL C(int n, int m) { return fac[n] * ifac[m] % Mod * ifac[n - m] % Mod; } LL S1(int n, int k) { if (f[k]) return f[k]; f[k] = pown[k + 1] - 1; rep(i, k) (f[k] -= C(k + 1, i) * S1(n, i) % Mod) %= Mod; ((((f[k] *= Pow(k + 1, Mod - 2)) %= Mod) += Mod) %= Mod); return
f[k]; } int main() { #ifdef hany01 File("51nod1229"); #endif fac[0] = 1; For(i, 1, maxk - 5) fac[i] = fac[i - 1] * i % Mod; ifac[maxk - 5] = Pow(fac[maxk - 5], Mod - 2); Fordown(i, maxk - 5, 1) ifac[i - 1] = ifac[i] * i % Mod; for (static int T = read(); T --; ) { scanf("%lld", &n), k = read(), scanf("%lld", &r); if (r == 1) { pown[0] = 1; For(i, 1, k + 1) pown[i] = pown[i - 1] * (n + 1) % Mod; printf("%lld\n", S1(n, k)); continue; } LL inv = Pow(r - 1, Mod - 2); S[0] = (Pow(r, n + 1) - r) % Mod * inv % Mod; For(i, 1, k) { S[i] = Pow(n, i) * Pow(r, n + 1) % Mod; For(j, 0, i - 1) (S[i] += (((i - j) & 1 ? -1 : 1) * C(i, j) * S[j] % Mod)) %= Mod; (S[i] *= inv) %= Mod; } printf("%lld\n", (S[k] + Mod) % Mod); } return 0; } //共看明月應垂淚,一夜鄉心五處同。 // -- 白居易《望月有感》