#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define vll vector #define vvvl vector #define vvl vector> #define VV(a, b, c, d) vector>(a, vector(b, c)) #define VVV(a, b, c, d) vector(a, vvl(b, vll (c, d))); #define re(c, b) for(ll c=0;c0){ if(b%2) ret = (ret*num)%p; num = (num*num)%p; b /= 2; } return ret; } struct MontgomeryReduction{ uint64_t MOD; uint64_t NEG_INV; uint64_t R2; MontgomeryReduction(uint64_t MOD_): MOD(MOD_){ NEG_INV = 0; uint64_t s = 1, t = 0; for(int i=0;i<64;i++){ if (~t & 1) { t += MOD; NEG_INV += s; } t >>= 1; s <<= 1; } R2 = ((uint64_t)1<<32) % MOD; R2 = R2 * R2 % MOD; } // return x * R % MOD; inline uint64_t generate(uint64_t x) const{ //assert(x < MOD); return reduce(x * R2); } // return x / R % MOD; inline uint64_t reduce(uint64_t x) const{ //assert(x < (MOD * MOD)); x = (x + ((uint32_t)x * (uint32_t)NEG_INV) * MOD) >> 32; return x < MOD? x: x-MOD; } }; ll inner_adjacentInterpolation(const vector &y, uint64_t p, uint64_t MOD, const vector &inv){ int n = y.size(); MontgomeryReduction mr(MOD); vector finv(n+1); uint64_t one = mr.generate(1); finv[0] = finv[1] = one; for(int i=2;i<=n;i++) finv[i] = mr.reduce(finv[i-1]*inv[i]); uint64_t M = one, ret = 0; for(int i=0;i>= 1; } mul = mr.reduce(mr.reduce(iC * val)); } ret += mul; } return ((ret%MOD) * M)%MOD; } ll exPowerSum(ll r, ll d, ll n, ll MOD){ if(n==0) return 0; n--; vector y(d+2), z(d+2), tbl(d+2); MontgomeryReduction m(MOD); //d乗テーブル ll cnt = d; for(int i=0;i>= 1; } r = (r%MOD + MOD)%MOD; uint64_t tmp = 0, rs = m.generate(1), R = m.generate(r); ll last = mpow(r, n%(MOD-1), MOD); n %= MOD; for(int i=0;i= MOD) tmp -= MOD; y[i] = tmp; rs = m.reduce(rs * R); } //z, tblを使い回す z[0] = m.generate(1); z[1] = m.generate((MOD - r)%MOD); tbl[0] = m.generate(0); tbl[1] = m.generate(1); uint64_t comb = m.generate(1), c = 0; for(int i=2;i<=d+1;i++) { tbl[i] = m.reduce(m.generate(MOD - (MOD/i))*tbl[MOD%i]); z[i] = m.reduce(z[i-1] * z[1]); } if(r==1) return inner_adjacentInterpolation(y, n, MOD, tbl); for(ll i=0;i= MOD) di -= MOD; c = (c * mpow(mpow(di, d+1, MOD), MOD-2, MOD))%MOD; uint64_t powerRinv = m.generate(1); uint64_t rinv = m.generate(mpow(r, MOD-2, MOD)); for(int i=0;i= MOD) y[i] -= MOD; y[i] = m.reduce(m.reduce(m.generate(y[i]) * powerRinv)); powerRinv = m.reduce(powerRinv * rinv); } y.pop_back(); ll ans = (last * inner_adjacentInterpolation(y, n, MOD, tbl))%MOD; return (ans + c)%MOD; } int main(){ ll n, k;std::cin >> n >> k; std::cout << exPowerSum(1, k, n+1, 1000000007) << '\n'; }