1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| #include <bits/stdc++.h>
const int kMaxN = 1e6 + 5, kMod = 1e8 + 7;
namespace Modular { template<class T> T qpow(T bs, T idx, T kMod) { bs %= kMod; int ret = 1; for (; idx; idx >>= 1, bs = 1ll * bs * bs % kMod) if (idx & 1) ret = 1ll * ret * bs % kMod; return ret; } int inv(int x, int kMod) { x %= kMod; if (!x) { std::cerr << "inv error\n"; return 0; } return qpow(x, kMod - 2, kMod); } template<class T, const T kMod> T add(T x, T y) { if (x + y >= kMod) return x + y - kMod; else return x + y; }
template<class T, const T kMod> T sub(T x, T y) { if (x - y < 0) return x - y + kMod; else return x - y; }
template<class T, const T kMod> struct Mint { T x;
Mint() { x = 0; } template<class _T> Mint(_T _x) { x = _x; }
friend Mint operator +(Mint m1, Mint m2) { return Mint(Modular::add<T, kMod>(m1.x, m2.x)); } friend Mint operator -(Mint m1, Mint m2) { return Mint(Modular::sub<T, kMod>(m1.x, m2.x)); } friend Mint operator *(Mint m1, Mint m2) { return Mint(1ll * m1.x * m2.x % kMod); } friend Mint operator /(Mint m1, Mint m2) { return Mint(1ll * m1.x * inv(m2.x, kMod) % kMod); } Mint operator +=(Mint m2) { return x = Modular::add<T, kMod>(x, m2.x); } Mint operator -=(Mint m2) { return x = Modular::sub<T, kMod>(x, m2.x); } Mint operator *=(Mint m2) { return x = 1ll * x * m2.x % kMod; } Mint operator /=(Mint m2) { return x = 1ll * x * inv(m2.x, kMod) % kMod; }
template<class _T> friend Mint operator +(Mint m1, _T m2) { return Mint(Modular::add<T, kMod>(m1.x, m2 % kMod)); } template<class _T> friend Mint operator -(Mint m1, _T m2) { return Mint(Modular::sub<T, kMod>(m1.x, m2 % kMod)); } template<class _T> friend Mint operator *(Mint m1, _T m2) { return Mint(1ll * m1.x * m2 % kMod); } template<class _T> friend Mint operator /(Mint m1, _T m2) { return Mint(1ll * m1.x * inv(m2, kMod) % kMod); } template<class _T> Mint operator +=(_T m2) { return x = Modular::add<T, kMod>(x, m2); } template<class _T> Mint operator -=(_T m2) { return x = Modular::sub<T, kMod>(x, m2); } template<class _T> Mint operator *=(_T m2) { return x = 1ll * x * m2 % kMod; } template<class _T> Mint operator /=(_T m2) { return x = 1ll * x * inv(m2, kMod) % kMod; } template<class _T> friend Mint operator +(_T m1, Mint m2) { return Mint(Modular::add<T, kMod>(m1 % kMod, m2.x)); } template<class _T> friend Mint operator -(_T m1, Mint m2) { return Mint(Modular::sub<T, kMod>(m1 % kMod, m2)); } template<class _T> friend Mint operator *(_T m1, Mint m2) { return Mint(1ll * m1 * m2.x % kMod); } template<class _T> friend Mint operator /(_T m1, Mint m2) { return Mint(1ll * m1 * inv(m2.x, kMod) % kMod); } friend Mint operator -(Mint &m1) { return Mint(m1.x == 0 ? (kMod - 1) : (m1.x - 1)); } friend Mint operator --(Mint &m1) { return m1 = Mint(m1.x == 0 ? (kMod - 1) : (m1.x - 1)); } friend Mint operator ++(Mint &m1) { return m1 = Mint(m1.x == (kMod - 1) ? 0 : (m1.x + 1)); } friend bool operator ==(Mint m1, Mint m2) { return m1.x == m2.x; }
friend std::istream &operator >>(std::istream &is, Mint &m) { int x; is >> x; m = Mint(x); return is; } friend std::ostream &operator <<(std::ostream &os, Mint m) { os << m.x; return os; } }; }
using mint = Modular::Mint<int, kMod>;
int n, m; mint pw2, f[kMaxN];
mint Fac(int n) { mint ret = 1; for (int i = 1; i <= n; ++i) ret *= i; return ret; }
void dickdreamer() { std::cin >> n >> m; pw2 = 1; for (int i = 1; i <= n; ++i) pw2 *= 2; f[0] = 1; mint A = pw2 - 1; for (int i = 2; i <= m; ++i) { f[i] = A - f[i - 1] - f[i - 2] * (i - 1) * (pw2 - i + 1); A *= pw2 - i; } std::cout << f[m] / Fac(m) << '\n'; }
int32_t main() { #ifdef ORZXKR freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0); int T = 1; while (T--) dickdreamer(); return 0; }
|