1228 序列求和 幂和+伯努利数
来源:互联网 发布:用vb编写九九乘法表 编辑:程序博客网 时间:2024/06/11 01:53
http://www.cnblogs.com/topW2W/p/5413875.html
分析:本题题意就是求自然数的幂和,但是它的case比较多。对于求幂和本身就需要的时间复杂度,如果继
续用上述方法来求自然数的幂和,5000个case会TLE,接下来介绍另一个求自然数幂和的方法,它是基于伯
努利数的,公式描述如下
可以看出只要我们预处理出每一项,就可以在线性时间内求得自然数的幂和。前面的倒数可以用递推法求逆元
预处理,组合数也可以预处理,也可以先预处理,现在关键是如何预处理伯努利数。
伯努利数满足条件,且有
那么继续得到
这就是伯努利数的递推式,逆元部分同样可以预处理。
另外,此题中我还学到了一种O(n)的递推法求前n个逆元的方法,详情见下篇转的博客。
1228 序列求和
题目来源: HackerRank
基准时间限制:3 秒 空间限制:131072 KB 分值: 160 难度:6级算法题
收藏
关注
T(n) = n^k,S(n) = T(1) + T(2) + ...... T(n)。给出n和k,求S(n)。
例如k = 2,n = 5,S(n) = 1^2 + 2^2 + 3^2 + 4^2 + 5^2 = 55。
由于结果很大,输出S(n) Mod 1000000007的结果即可。
Input
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 5000)第2 - T + 1行:每行2个数,N, K中间用空格分割。(1 <= N <= 10^18, 1 <= K <= 2000)
Output
共T行,对应S(n) Mod 1000000007的结果。
Input示例
35 34 24 1
Output示例
2253010
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<iomanip> 6 using namespace std; 7 typedef long long LL; 8 const LL N = 2050; 9 const LL maxn = 2050;10 const LL mod = 1000000007;11 LL n, k;12 13 LL comb[maxn][maxn], ber[maxn];14 15 void ex_gcd(LL a, LL b, LL& d, LL& x, LL &y){16 if(b==0){17 x = 1; y = 0; d = a; 18 return ;19 }20 ex_gcd(b, a%b, d, y, x);21 y -= x*(a/b);22 }23 24 LL inv(LL a, LL p){25 LL x, y, d;26 ex_gcd(a, p, d, x, y);27 if(d==1) return (x%p + p)%p;28 else return 0;29 }30 31 void init_comb(){32 comb[0][0] = 1;33 for(int i = 1; i<maxn; ++i){34 comb[i][0] = comb[i][i] = 1;35 for(int j = 1 ; j<i; ++j){36 comb[i][j] = (comb[i-1][j-1]%mod + comb[i-1][j]%mod)%mod;37 }38 }39 }40 //求伯努利数41 void init_ber(){42 ber[0] = 1;43 for(int i = 1 ; i<maxn; ++i){44 LL ans = 0;45 for(int j = 0 ; j<i ; ++j)46 ans = (ans + comb[i+1][j]*ber[j])%mod;47 ans = -ans*inv(i+1, mod)%mod;48 ber[i] = (ans%mod + mod)%mod;49 }50 }51 52 //LL Inv[maxn];53 /*void bi(){54 Inv[1] = 1; 55 a for(int i=2; i<N; i++) 56 Inv[i] = (mod - mod / i) * Inv[mod % i] % mod; 57 //预处理伯努利数 58 for(int i= 1; i<100; ++i) cout<<Inv[i]<<" ";59 cout<<endl;60 for(int j= 1; j<100 ; ++j) cout<<inv(j,mod)<<" "; 61 }*/62 int main(){63 int T;64 cin>>T;65 init_comb();66 init_ber();67 while(T--){68 scanf("%lld %lld", &n, &k);69 n %= mod;70 LL ans = 0;71 LL pow = (n+1)%mod;72 for(int i = 1; i<=k+1 ; ++i){73 ans = (ans + comb[k+1][i]*ber[k+1-i]%mod*pow%mod)%mod; 74 pow = (pow*(n+1))%mod;75 }76 ans = ans*inv(k+1, mod)%mod;77 ans = (ans%mod + mod)%mod;78 printf("%lld\n", ans); 79 }80 }
阅读全文
0 0
- 1228 序列求和 幂和+伯努利数
- [51nod1228][伯努利数][自然数k次幂和]序列求和
- 51nod 1258 序列求和 V4 拉格朗日插值法求自然数幂和
- 51nod 1228 序列求和
- 51Nod-1228-序列求和
- 序列求和
- 序列求和
- 序列求和
- 序列求和
- 序列求和
- 序列求和
- 序列求和
- 序列求和
- 序列求和
- 序列求和
- 序列求和
- 序列求和
- 序列求和
- R中图形参数设置函数par()的使用
- 具体时间的表示
- 初级X编程----信息量挺大的
- php-fpm进程数优化方法
- zcmu-1988
- 1228 序列求和 幂和+伯努利数
- HashMap、HashTable、ConcurrentHashMap
- nginx基础学习
- css font-family的字体英文对照
- 【bzoj1015】[JSOI2008]星球大战 并查集
- 实验五 树和二叉树的实验1 树的顺序结构的实现
- OpenCV的互通性操作(各版本转换)
- 部署ftp
- [设计]备忘录模式