QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#29753 | #1285. Stirling Number | alpha1022 | AC ✓ | 75ms | 25264kb | C++14 | 2.8kb | 2022-04-22 13:03:17 | 2022-04-28 15:42:01 |
Judging History
answer
#include <cstdio>
#include <algorithm>
using namespace std;
int mod, G;
typedef long long ll;
typedef __uint128_t L;
struct FastMod {
ll b, m;
FastMod(ll b): b(b), m(ll((L(1) << 64) / b)) {}
ll operator()(ll a) {
ll q = (ll)((L(m) * a) >> 64);
ll r = a - q * b; // can be proven that 0 <= r < 2*b
return r >= b ? r - b : r;
}
} R(2);
inline int norm(int x) {
return x >= mod ? x - mod : x;
}
inline int reduce(int x) {
return x < 0 ? x + mod : x;
}
inline int mpow(int a, int b) {
int ret = 1;
for (; b; b >>= 1) {
if (b & 1)
ret = R((ll)ret * a);
a = R((ll)a * a);
}
return ret;
}
const int M = 1e6;
ll n, st, ed, k;
int r;
int GPow[M], GLog[M], inv[M];
int fac[M], ifac[M];
int a[M];
inline int getG() {
int p[20], cnt = 0;
int t = mod - 1;
for (int i = 2; i * i <= t; ++i) {
if (t % i == 0)
p[cnt++] = i;
while (t % i == 0)
t /= i;
}
if (t > 1)
p[cnt++] = t;
for (int G = 2; ; ++G) {
bool flag = 1;
for (int i = 0; i < cnt; ++i)
if (mpow(G, (mod - 1) / p[i]) == 1) {
flag = 0;
break;
}
if (flag)
return G;
}
}
int binom(ll n, ll m) {
if (n < m || m < 0)
return 0;
if (n < mod)
return R(R((ll)fac[n] * ifac[m]) * ifac[n - m]);
return R((ll)binom(n / mod, m / mod) * binom(n % mod, m % mod));
}
int calc(ll m, ll n) {
if (m < 0)
return 0;
m = min(n, m);
if (n < mod) {
int ret = R((ll)a[0] * (m + 1));
for (int k = 1, t = 0; k < mod - 1; ++k)
t = t >= m + 1 ? t - m - 1 : t - m - 1 + mod - 1,
ret = R(R((ll)(GPow[t] - 1) * inv[GPow[mod - 1 - k] - 1]) * a[k] + ret);
ret = reduce(-ret);
return ret;
}
m -= k;
if (m < 0)
return 0;
ll a = m / (mod - 1);
int b = m % (mod - 1);
int tmp = binom(k - 1, a);
if ((k - a - 1) & 1)
tmp = reduce(-tmp);
int ret = R((ll)tmp * (calc(b - mod + 1, r) - calc(b, r) + mod));
if (b < r && a > 0) {
tmp = binom(k - 1, a - 1);
if ((k - a) & 1)
tmp = reduce(-tmp);
ret = R((ll)tmp * (calc(b, r) - calc(b + mod - 1, r) + mod) + ret);
}
return ret;
}
int main() {
scanf("%lld%lld%lld%d", &n, &st, &ed, &mod);
R = FastMod(mod), G = getG();
GPow[0] = 1;
for (int i = 1; i < mod - 1; ++i)
GLog[GPow[i] = R((ll)GPow[i - 1] * G)] = i;
inv[1] = 1;
for (int i = 2; i < mod - 1; ++i)
inv[i] = GPow[mod - 1 - GLog[i]];
fac[0] = ifac[0] = 1;
for (int i = 1; i <= mod - 1; ++i)
fac[i] = R((ll)fac[i - 1] * i),
ifac[i] = R((ll)ifac[i - 1] * inv[i]);
k = n / mod, r = n % mod;
for (int k = 0; k < mod - 1; ++k) {
int x = GPow[k];
if (x < mod - r + 1)
a[k] = R((ll)fac[x + r - 1] * ifac[x - 1]);
}
printf("%d\n", reduce(calc(ed, n) - calc(st - 1, n)));
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 12024kb
input:
4 1 4 5
output:
4
result:
ok "4"
Test #2:
score: 0
Accepted
time: 4ms
memory: 12068kb
input:
6 5 5 29
output:
15
result:
ok "15"
Test #3:
score: 0
Accepted
time: 51ms
memory: 25204kb
input:
1000 685 975 999983
output:
482808
result:
ok "482808"
Test #4:
score: 0
Accepted
time: 0ms
memory: 11968kb
input:
8 7 8 7
output:
1
result:
ok "1"
Test #5:
score: 0
Accepted
time: 4ms
memory: 12000kb
input:
6 4 6 3
output:
2
result:
ok "2"
Test #6:
score: 0
Accepted
time: 0ms
memory: 9956kb
input:
31494923 16387579 27674098 2
output:
0
result:
ok "0"
Test #7:
score: 0
Accepted
time: 8ms
memory: 17448kb
input:
1000000000 179971578 813833436 383101
output:
53093
result:
ok "53093"
Test #8:
score: 0
Accepted
time: 21ms
memory: 18012kb
input:
1000000000 243662537 919841454 336437
output:
75332
result:
ok "75332"
Test #9:
score: 0
Accepted
time: 46ms
memory: 25212kb
input:
1000000000 802415407 880806868 999983
output:
960771
result:
ok "960771"
Test #10:
score: 0
Accepted
time: 48ms
memory: 25264kb
input:
1000000000 644768002 859679621 999983
output:
805072
result:
ok "805072"
Test #11:
score: 0
Accepted
time: 48ms
memory: 25216kb
input:
1000000000 413491669 805704689 999983
output:
138470
result:
ok "138470"
Test #12:
score: 0
Accepted
time: 68ms
memory: 25200kb
input:
48537068788 22847195743 28163317559 999983
output:
529264
result:
ok "529264"
Test #13:
score: 0
Accepted
time: 56ms
memory: 25168kb
input:
828536325370 779765412000 782633091631 999983
output:
836701
result:
ok "836701"
Test #14:
score: 0
Accepted
time: 57ms
memory: 25264kb
input:
258077969836231211 200983000620029238 226661348290193221 999983
output:
104488
result:
ok "104488"
Test #15:
score: 0
Accepted
time: 65ms
memory: 25260kb
input:
258904208719347339 185679775210965354 223112834501603079 999983
output:
0
result:
ok "0"
Test #16:
score: 0
Accepted
time: 51ms
memory: 25244kb
input:
259730451897430763 53367210716367086 159749126385022258 999983
output:
0
result:
ok "0"
Test #17:
score: 0
Accepted
time: 75ms
memory: 25184kb
input:
260556695075514187 28149045695465635 29562653808086859 999983
output:
669091
result:
ok "669091"
Test #18:
score: 0
Accepted
time: 44ms
memory: 24580kb
input:
1000000000000000000 199156813867768126 571262092911942493 919337
output:
732102
result:
ok "732102"
Test #19:
score: 0
Accepted
time: 55ms
memory: 25200kb
input:
353534534534 1999983 2234324324 999983
output:
613376
result:
ok "613376"
Test #20:
score: 0
Accepted
time: 46ms
memory: 25204kb
input:
353534534534 0 2234324324 999983
output:
520965
result:
ok "520965"
Test #21:
score: 0
Accepted
time: 42ms
memory: 25208kb
input:
353534534534 22342343 353534534534 999983
output:
281927
result:
ok "281927"