QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#29753#1285. Stirling Numberalpha1022AC ✓75ms25264kbC++142.8kb2022-04-22 13:03:172022-04-28 15:42:01

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-04-28 15:42:01]
  • 评测
  • 测评结果:AC
  • 用时:75ms
  • 内存:25264kb
  • [2022-04-22 13:03:17]
  • 提交

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"