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
| #include <bits/stdc++.h>
#define int int64_t
const int kMaxK = 205, kMod = 1e9 + 7, kInv2 = 500000004, kInv5 = 400000003;
int k, l, r; int C[kMaxK][kMaxK], S[kMaxK][kMaxK], fac[kMaxK], ifac[kMaxK];
constexpr int qpow(int bs, int64_t idx = kMod - 2) { int ret = 1; for (; idx; idx >>= 1, bs = (int64_t)bs * bs % kMod) if (idx & 1) ret = (int64_t)ret * bs % kMod; return ret; }
inline int add(int x, int y) { return (x + y >= kMod ? x + y - kMod : x + y); } inline int sub(int x, int y) { return (x >= y ? x - y : x - y + kMod); } inline void inc(int &x, int y) { (x += y) >= kMod ? x -= kMod : x; } inline void dec(int &x, int y) { (x -= y) < 0 ? x += kMod : x; }
int getop(int x) { return (~x & 1) ? 1 : (kMod - 1); }
struct Node { int a, b;
Node(int _a = 0, int _b = 0) : a(_a), b(_b) {}
Node inv() { int k = qpow(sub(1ll * a * a % kMod, 5ll * b % kMod * b % kMod)); return {1ll * a * k % kMod, 1ll * sub(0, b) * k % kMod}; }
friend bool operator ==(Node a, Node b) { return a.a == b.a && a.b == b.b; } friend Node operator +(Node a, Node b) { return {add(a.a, b.a), add(a.b, b.b)}; } friend Node operator -(Node a, Node b) { return {sub(a.a, b.a), sub(a.b, b.b)}; } friend Node operator *(Node a, Node b) { return {add(1ll * a.a * b.a % kMod, 5ll * a.b % kMod * b.b % kMod), add(1ll * a.a * b.b % kMod, 1ll * a.b * b.a % kMod)}; } friend Node operator /(Node a, Node b) { return a * b.inv(); } friend Node operator -(Node a) { return {sub(0, a.a), sub(0, a.b)}; } };
Node qpow(Node bs, int idx) { Node ret = {1, 0}; for (; idx; idx >>= 1, bs = bs * bs) if (idx & 1) ret = ret * bs; return ret; }
int getsum(int n, int k) { if (!n) return 0; Node ret = {0, 0}, a = {kInv2, kInv2}, b = {kInv2, sub(0, kInv2)}; for (int i = 0; i <= k; ++i) { Node bs = qpow(a, i) * qpow(b, k - i), sum = {0, 0}; if (bs == (Node){1, 0}) sum = {n % kMod, 0}; else sum = (qpow(bs, n + 1) - bs) / (bs - (Node){1, 0}); if (~(k - i) & 1) ret = ret + sum * (Node){C[k][i], 0}; else ret = ret - sum * (Node){C[k][i], 0}; } if (~k & 1) return 1ll * ret.a * qpow(kInv5, k / 2) % kMod; else return 1ll * ret.b * qpow(kInv5, k / 2) % kMod; }
int getsum(int l, int r, int k) { return sub(getsum(r, k), getsum(l - 1, k)); }
void prework() { fac[0] = ifac[0] = C[0][0] = S[0][0] = 1, 1; for (int i = 1; i <= 200; ++i) { C[i][0] = 1; fac[i] = 1ll * i * fac[i - 1] % kMod; ifac[i] = qpow(fac[i]); for (int j = 1; j <= i; ++j) { C[i][j] = add(C[i - 1][j - 1], C[i - 1][j]); S[i][j] = add(S[i - 1][j - 1], 1ll * (i - 1) * S[i - 1][j] % kMod); } } }
void dickdreamer() { prework(); std::cin >> k >> l >> r; l += 2, r += 2; int ans = 0; for (int i = 0; i <= k; ++i) { inc(ans, 1ll * S[k][i] * getop(k - i) % kMod * getsum(l, r, i) % kMod); } std::cout << 1ll * ans * ifac[k] % kMod << '\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; }
|