1.伯努利数能干啥
伯努利数求自然幂和
2.怎么得到啊
1. 递推
题目: 51nod 序列求和V2
code:
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
const int mod = 1e9+7;
ll inv[maxn],fac[maxn],iinv[maxn];
ll B[maxn];
ll qpow(ll a,ll b){
a %= mod;
ll ret = 1;
while(b){
if(b&1) ret = ret * a % mod;
a = a * a % mod;
b >>= 1;
}
return ret;
}
ll Inv(ll n){
return qpow(n,mod-2);
}
void Add(ll& x,ll y){
x += y;
if(x>=mod) x -= mod;
}
void Mul(ll& x,ll y){
x *= y;
if(x>=mod) x %=mod;
}
inline ll C(int n, int m) {
return fac[n] * iinv[n - m] % mod*iinv[m] % mod;
}
void init() {
fac[0] = fac[1] = inv[0] = inv[1] = 1;
iinv[0] = iinv[1] = 1;
for(int i = 2; i <maxn; i++) fac[i] = fac[i - 1] * i %mod;
for(int i = 2; i <maxn; i++) inv[i] = inv[mod % i] * (mod - mod/i) % mod;
for(int i = 2; i <maxn; i++) iinv[i] = iinv[i-1] * inv[i] % mod;
B[0] = 1;
for(int i = 1;i<2005;i++){
B[i] = 0;
for(int j = 0;j<i;j++){
Add(B[i],C(i+1,j) * B[j] % mod);
}
Mul(B[i],inv[i+1]);
B[i] = -B[i];
Add(B[i],mod);
}
}
int main(){
init();
int T;
scanf("%d",&T);
while(T--){
ll n,k;
scanf("%lld%lld",&n,&k);
ll ans = 0;
for(int i = 1;i<= k+1;i++){
ll ret = C(k+1,i);
Mul(ret,B[k+1-i]);
Mul(ret,qpow(n+1,i));
Mul(ret,inv[k+1]);
Add(ans,ret);
}
printf("%lld\n",ans);
}
return 0;
}
2.多项式求逆元
注意求出的 要乘上 才是伯努利数。
题目:51nod 序列求和V4
code:用的是三模数NTT方法处理任意模数。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 5e5 + 10 , g = 3;
const int M[] = {998244353,1004535809,469762049};
const ll _M = (ll)M[0] * M[1];
const int mod = 1e9 + 7;
const double eps = 1e-3;
int rev[maxn];
ll fac[maxn],inv[maxn];
ll qmul(ll a, ll b, ll c){
a %= c; b %= c;
ll ret = a * b - (ll)((long double)a * b / c + eps) * c;
return ret < 0 ? ret + c : ret;
}
inline ll qpow(ll a,ll b,ll P){
ll ret = 1;
a %= P;
for(;b;b>>=1,a=a*a%P) if(b&1) ret = ret * a % P;
return ret;
}
const int m1 = M[0],m2 = M[1],m3 = M[2];
const int inv1 = qpow(m1 % m2,m2-2,m2);
const int inv2 = qpow(m2 % m1,m1-2,m1);
const int inv12 = qpow(_M % m3,m3-2,m3);
ll CRT(ll a1, ll a2, ll a3){
ll ret = qmul(a1 * m2 % _M, inv2, _M);
(ret += qmul(a2 * m1 % _M, inv1, _M)) %= _M;
ll ans = ((a3 - ret) % m3 + m3) % m3 * inv12 % m3;
ans = (ans % mod * (_M % mod) % mod + ret % mod) % mod;
return ans;
}
inline ll C(int n, int m){
return fac[n] * inv[n - m] % mod * inv[m] % mod;
}
void init(int n){
fac[0] = fac[1] = inv[0] = inv[1] = 1;
for (int i = 2; i <= n; i++) fac[i] = fac[i - 1] * i % mod;
for (int i = 2; i <= n; i++) inv[i] = inv[mod % i] * (mod - mod / i) % mod;
for (int i = 2; i <= n; i++) inv[i] = inv[i-1] * inv[i] % mod;
}
struct NTT{
int P;
int num,w[2][maxn];
void Pre(int _P,int m){
num = m; P = _P;
int wn = qpow(g,(P-1)/num,P);
int _wn = qpow(wn,P-2,P);
w[1][0] = w[0][0] = 1;
for(int i = 1;i<num;i++) w[1][i] = (ll)w[1][i-1] * wn % P;
for(int i = 1;i<num;i++) w[0][i] = (ll)w[0][i-1] * _wn % P;
}
void DFT(int* a,int N,int r){
for(int i = 1;i<N;i++) if(i<rev[i]) swap(a[i],a[rev[i]]);
for(int i = 1;i<N;i<<=1)
for(int j = 0;j<N;j+=(i<<1))
for(int k = 0;k<i;k++){
int x = a[j+k],y = 1LL * a[i+j+k] * w[r][num/(i<<1)*k] % P;
a[j+k] = (x+y) % P; a[i+j+k] = (x + P - y) % P;
}
if(!r) for(int i = 0,Inv = qpow(N,P-2,P);i<N;i++) a[i] = 1LL * a[i] * Inv % P;
}
}ntt[3];
int tmp[maxn],_b[3][maxn],c[maxn],a[maxn],b[maxn];
void Get_Inv(int* a,int* b,int n){
if(n == 1){
b[0] = qpow(a[0],mod-2,mod);
return ;
}
Get_Inv(a,b,n>>1);
int L = 0; while(!(n>>L&1)) L++;
for(int i = 1;i<(n<<1);i++) rev[i] = (rev[i>>1]>>1)|((i&1)<<L);
for(int k = 0;k<3;k++)
for(int i = 0;i<n;i++) _b[k][i] = b[i],_b[k][i+n] = 0;
for(int k = 0;k<3;k++){
for(int i = 0;i<n;i++) tmp[i] = a[i],tmp[i+n] = 0;
ntt[k].DFT(tmp,n<<1,1); ntt[k].DFT(_b[k],n<<1,1);
for(int i = 0;i<(n<<1);i++) _b[k][i] = 1LL *_b[k][i] * tmp[i] % ntt[k].P;
ntt[k].DFT(_b[k],n<<1,0);
}
for(int i = 0;i<n;i++) _b[0][i]=_b[1][i]=_b[2][i] = (mod - CRT(_b[0][i],_b[1][i],_b[2][i])) % mod;
_b[0][0] = _b[1][0] = _b[2][0] = (_b[0][0] + 2) % mod;
for(int k = 0;k<3;k++){
for(int i = 0;i<n;i++) tmp[i] = b[i],tmp[i+n] = 0;
ntt[k].DFT(tmp,n<<1,1); ntt[k].DFT(_b[k],n<<1,1);
for(int i = 0;i<(n<<1);i++) _b[k][i]=1LL*_b[k][i] * tmp[i] % ntt[k].P;
ntt[k].DFT(_b[k],n<<1,0);
}
for(int i = 0;i<n;i++) b[i] = CRT(_b[0][i],_b[1][i],_b[2][i]);
}
int main(){
int N = 1;
for(N = 1;N<=50001;N<<=1);
init(N+1);
ntt[0].Pre(m1,N<<1);
ntt[1].Pre(m2,N<<1);
ntt[2].Pre(m3,N<<1);
for(int i = 0;i<N;i++) a[i] = inv[i+1];
Get_Inv(a,b,N);
for(int i = 0;i<N;i++) b[i] = 1LL*b[i] * fac[i] % mod;
int T;
scanf("%d",&T);
while(T--){
ll n;
int k;
scanf("%lld%d",&n,&k);
n %= mod;
ll ans = 0;
ll p = 1;
for(int i = 1;i<=k+1;i++){
p = p * (n+1) % mod;
ans += C(k+1,i)*b[k+1-i] % mod * p % mod;
ans %= mod;
}
ans = ans * inv[k+1] % mod * fac[k] % mod;
printf("%lld\n",ans);
}
return 0;
}