51Nod 1228 伯努利数
题目链接:
题意:
S(k,n)=1^k+2^k+...+n^k求自然数幂和对1e9+7取模。
限制:
1<= n <= 10^18; 1 <= k <= 2000
思路:
伯努利数
S(k,n)=S(k,n)=1/(k+1) * ( C(k+1,k)*B[k]*(n+1)^1 + C(k+1,k-1)*B[k-1]*(n+1)^2 + ... + C(k+1,0)*B[0]*(n+1)^(k+1) )(B[i]为伯努利数)
而B[n]有:
B[n]=-1/(n+1) * ( C(n+1,0)*B[0] + C(n+1,1)*B[1] + ... + C(n+1,n-1)*B[n-1] )
所以B[0]...B[k]可以O(k^2)预处理出来,然后对于每个S(k,n)可以O(k)算出来。
/*51NOD 1228
题意:
S(k,n)=1^k+2^k+...+n^k
求自然数幂和对1e9+7取模。
限制:
1<= n <= 10^18; 1 <= k <= 2000
思路:
伯努利数
S(k,n)=S(k,n)=1/(k+1) * ( C(k+1,k)*B[k]*(n+1)^1 + C(k+1,k-1)*B[k-1]*(n+1)^2 + ... + C(k+1,0)*B[0]*(n+1)^(k+1) ) (B[i]为伯努利数)
而B[n]有:
B[n]=-1/(n+1) * ( C(n+1,0)*B[0] + C(n+1,1)*B[1] + ... + C(n+1,n-1)*B[n-1] )
所以B[0]...B[k]可以O(k^2)预处理出来,然后对于每个S(k,n)可以O(k)算出来。
*/
#include
#include
using namespace std;
#define LL __int64
const int MOD=1000000007;
LL Ext_gcd(LL a,LL b,LL &x,LL &y){
if(b==0) { x=1, y=0; return a; }
LL ret= Ext_gcd(b,a%b,y,x);
y-= a/b*x;
return ret;
}
LL Inv(LL a,int m){ //求逆元
LL d,x,y,t= (LL)m;
d= Ext_gcd(a,t,x,y);
if(d==1) return (x%t+t)%t;
return -1;
}
const int N=2005;
LL B[N],C[N][N];
void init(){
for(int i=0;i