1 ~ n的k次方求和模板

tech2023-02-28  106

∑ i = 1 n i k \sum\limits_{i = 1} ^{n} i ^ k i=1nik

/* Author : lifehappy */ #pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const double eps = 1e-7; const int N = 1e6 + 10, mod = 1e9 + 7; ll fac[N], pre[N], suc[N], inv[N], prime[N], sum[N], n, k, cnt; bool st[N]; ll quick_pow(ll a, int n) { ll ans = 1; while(n) { if(n & 1) ans = ans * a % mod; a = a * a % mod; n >>= 1; } return ans; } void init() { sum[1] = 1; for(int i = 2; i < N; i++) { if(!st[i]) { prime[cnt++] = i; sum[i] = quick_pow(i, k); } for(int j = 0; j < cnt && i * prime[j] < N; j++) { st[i * prime[j]] = 1; sum[i * prime[j]] = 1ll * sum[i] * sum[prime[j]] % mod; if(i % prime[j] == 0) break; } } fac[0] = inv[0] = 1; for(int i = 1; i < N; i++) { sum[i] = (sum[i] + sum[i - 1]) % mod; fac[i] = 1ll * fac[i - 1] * i % mod; } inv[N - 1] = quick_pow(fac[N - 1], mod - 2); for(int i = N - 2; i >= 1; i--) { inv[i] = 1ll * inv[i + 1] * (i + 1) % mod; } } ll solve(ll n, int k) { ll ans = 0; init(); pre[0] = suc[k + 3] = 1; for(int i = 1; i <= k + 2; i++) pre[i] = 1ll * pre[i - 1] * (n - i) % mod; for(int i = k + 2; i >= 1; i--) suc[i] = 1ll * suc[i + 1] * (n - i) % mod; for(int i = 1; i <= k + 2; i++) { ll a = 1ll * pre[i - 1] * suc[i + 1] % mod, b = 1ll * inv[i - 1] * inv[k + 2 - i] % mod; if((k + 2 - i) & 1) b *= -1; ans = ((ans + 1ll * sum[i] * a % mod * b % mod) % mod + mod) % mod; } return ans; } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); scanf("%lld %lld", &n, &k); printf("%lld\n", solve(n, k)); return 0; }
最新回复(0)