#include <algorithm>
#include <iostream>
#include <vector>
#include <list>
#include <cassert>
#include <map>
#include <numeric>
using namespace std;
#define FOR(i, n) for(int i = 0, __n = (n); i < __n; i++)
static const long long MOD = 1000000007LL;
struct Frac {
long long v;
Frac(long long x = 0) {
x %= MOD;
if (x < 0) x += MOD;
v = x;
}
Frac(long long num, long long den) {
num %= MOD;
if (num < 0) num += MOD;
den %= MOD;
if (den < 0) den += MOD;
v = num * Frac(den).inv().v % MOD;
}
Frac pow(long long e) const {
long long a = v;;
long long r = 1;
while (e > 0) {
if (e & 1) r = r * a % MOD;
a = a * a % MOD;
e >>= 1;
}
return r;
}
Frac inv() const {
return pow(MOD - 2);
}
Frac operator+(const Frac& other) const {
return Frac(v + other.v);
}
Frac operator-(const Frac& other) const {
return Frac(v - other.v);
}
Frac operator*(const Frac& other) const {
return Frac(v * other.v % MOD);
}
Frac operator/(const Frac& other) const {
return Frac(v * other.inv().v % MOD);
}
Frac& operator+=(const Frac& other) {
v += other.v;
if (v >= MOD) v -= MOD;
return *this;
}
Frac& operator-=(const Frac& other) {
v -= other.v;
if (v < 0) v += MOD;
return *this;
}
};
const int MAXN = 1000010;
Frac p[MAXN]; // prawdopodobienstwo dojscia 1 gracza do x w grze 1-os
Frac r[MAXN+1]; // prawdopodobienstwo, ze gra sie skończy od x (1os)
int main() {
int n, k, m;
cin >> n >> k >> m;
Frac inv_k = Frac(1, k);
int lim = max(0, m - k);
p[0] = 1;
Frac window = 0;
FOR(i, m) {
window += p[i] * inv_k;
if (i >= k) {
window -= p[i-k] * inv_k;
}
p[i+1] = window;
}
r[m] = 0;
for(int i = m-1; i >= 0; i--) {
if (i >= lim) {
Frac koniec = p[i] * inv_k * Frac(i+k-m+1);
r[i] = r[i+1] + koniec;
} else {
r[i] = 1;
}
}
Frac res = 0;
FOR(i, m) {
if(i < lim) {
res += p[i] * n;
} else {
res += p[i] * (r[i].pow(n) - r[i+1].pow(n))/(r[i] - r[i+1]);
}
}
cout << res.v << endl;
return 0;
}
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 118 119 120 121 122 | #include <algorithm> #include <iostream> #include <vector> #include <list> #include <cassert> #include <map> #include <numeric> using namespace std; #define FOR(i, n) for(int i = 0, __n = (n); i < __n; i++) static const long long MOD = 1000000007LL; struct Frac { long long v; Frac(long long x = 0) { x %= MOD; if (x < 0) x += MOD; v = x; } Frac(long long num, long long den) { num %= MOD; if (num < 0) num += MOD; den %= MOD; if (den < 0) den += MOD; v = num * Frac(den).inv().v % MOD; } Frac pow(long long e) const { long long a = v;; long long r = 1; while (e > 0) { if (e & 1) r = r * a % MOD; a = a * a % MOD; e >>= 1; } return r; } Frac inv() const { return pow(MOD - 2); } Frac operator+(const Frac& other) const { return Frac(v + other.v); } Frac operator-(const Frac& other) const { return Frac(v - other.v); } Frac operator*(const Frac& other) const { return Frac(v * other.v % MOD); } Frac operator/(const Frac& other) const { return Frac(v * other.inv().v % MOD); } Frac& operator+=(const Frac& other) { v += other.v; if (v >= MOD) v -= MOD; return *this; } Frac& operator-=(const Frac& other) { v -= other.v; if (v < 0) v += MOD; return *this; } }; const int MAXN = 1000010; Frac p[MAXN]; // prawdopodobienstwo dojscia 1 gracza do x w grze 1-os Frac r[MAXN+1]; // prawdopodobienstwo, ze gra sie skończy od x (1os) int main() { int n, k, m; cin >> n >> k >> m; Frac inv_k = Frac(1, k); int lim = max(0, m - k); p[0] = 1; Frac window = 0; FOR(i, m) { window += p[i] * inv_k; if (i >= k) { window -= p[i-k] * inv_k; } p[i+1] = window; } r[m] = 0; for(int i = m-1; i >= 0; i--) { if (i >= lim) { Frac koniec = p[i] * inv_k * Frac(i+k-m+1); r[i] = r[i+1] + koniec; } else { r[i] = 1; } } Frac res = 0; FOR(i, m) { if(i < lim) { res += p[i] * n; } else { res += p[i] * (r[i].pow(n) - r[i+1].pow(n))/(r[i] - r[i+1]); } } cout << res.v << endl; return 0; } |
English