51nod 1228 序列求和 ( 1^k+2^k+3^k+...+n^k )
C为组合数,B为伯努利数
具体推到过程略
参考博客:http://blog.csdn.net/acdreamers/article/details/38929067#
(我的式子和博客中的不一样,不过思想是一样的)
具体见代码:
1 const int MOD = 1000000000 + 7; 2 3 4 const int maxn = 2000 + 10; 5 LL C[maxn][maxn]; 6 LL inv[maxn]; 7 LL B[maxn]; 8 LL n, k; 9 void init() 10 { 11 scanf("%lld%lld", &n, &k); 12 } 13 14 void getC() 15 { 16 C[0][0] = 1; 17 for(int i = 1; i < maxn; i++) { 18 C[i][0] = C[i][i] = 1; 19 for(int j = 1; j < i; j++) 20 C[i][j] = (C[i-1][j] + C[i-1][j-1]) % MOD; 21 } 22 } 23 24 void getInv() //O(n) 求所有逆元 25 { 26 inv[1] = 1; 27 for (int i = 2; i < maxn; i++) 28 { 29 inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD; 30 } 31 } 32 33 void getB() //求伯努利数 34 { 35 B[0] = 1; 36 for (int i = 1; i < maxn - 1; i++) 37 { 38 for (int j = 0; j < i; j++) 39 { 40 B[i] = (B[i] + C[i+1][j] * B[j]) % MOD; 41 } 42 B[i] = (-inv[i+1] * B[i] % MOD + MOD) % MOD; 43 } 44 } 45 46 LL ni[maxn]; 47 void solve() 48 { 49 n %= MOD; //1e18会爆 50 ni[0] = 1; 51 for (int i = 1; i <= k + 1; i++) ni[i] = ni[i-1] * (n + 1) % MOD; 52 LL ans = 0; 53 for (int i = 0; i <= k; i++) 54 { 55 ans = (ans + C[k+1][i] * ni[k+1-i] % MOD * B[i] % MOD) % MOD; 56 } 57 ans = ans * inv[k+1] % MOD; 58 printf("%lld\n", ans); 59 } 60 61 int main() 62 { 63 getInv(); 64 getC(); 65 getB(); 66 int T; 67 scanf("%d", &T); 68 while (T--) 69 { 70 init(); 71 solve(); 72 } 73 return 0; 74 }