結果
| 問題 |
No.2705 L to R Graph (Another ver.)
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-05-25 13:20:51 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 4,654 bytes |
| コンパイル時間 | 2,076 ms |
| コンパイル使用メモリ | 173,604 KB |
| 実行使用メモリ | 40,264 KB |
| 最終ジャッジ日時 | 2024-12-20 19:47:05 |
| 合計ジャッジ時間 | 171,884 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 10 TLE * 40 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
#define debug(...) fprintf(stderr, __VA_ARGS__)
using LL = long long;
const int N = 1e5 + 5;
struct Mod {
LL m, p;
void init(LL pp) {
p = pp;
m = (__int128(1) << 64) / p;
}
LL operator()(LL x) {
return x - (__int128(x) * m >> 64) * p;
}
} mod;
int P;
inline LL qp(LL a, LL b = P - 2) {
LL c = 1;
while (b) {
if (b & 1) c = mod(c * a);
a = mod(a * a);
b /= 2;
}
return c;
}
LL fac[N], ifac[N], pn[N];
void initC(int n) {
fac[0] = 1;
for (int i = 1; i <= n; ++i) fac[i] = mod(fac[i - 1] * i);
ifac[n] = qp(fac[n]);
for (int i = n; i > 0; --i) ifac[i - 1] = mod(ifac[i] * i);
}
inline LL binom(int n, int m) {
if (n < m || m < 0) return 0;
return mod(mod(fac[n] * ifac[m]) * ifac[n - m]);
}
LL mu[N];
void initP(int n) {
int m = 0;
static LL v[N], p[N];
mu[1] = 1;
for (int i = 2; i <= n; ++i) {
if (!v[i]) v[i] = i, p[++m] = i, mu[i] = -1;
for (int j = 1; j <= m && p[j] * i <= n; ++j) {
v[p[j] * i] = p[j];
if (i % p[j] == 0) {
mu[p[j] * i] = 0;
} else {
mu[p[j] * i] = -mu[i];
}
}
}
}
int n;
LL f[N], g[N];
vector<int> d[N];
void initD(int n) {
for (int i = 1; i <= n; ++i) {
for (int j = i; j <= n; j += i) {
d[j].push_back(i);
}
}
}
void calcF() {
static LL s[N];
for (int j = 1; j < n; ++j) {
for (int l = 1; l <= j; ++l) {
int L = l, R = j;
auto F = [&](int x) {
return (j - 1) / (j / x) + 1;
};
while (L < R) {
int mid = (L + R + 1) / 2;
if (F(mid) != F(L)) R = mid - 1;
else L = mid;
}
auto r = F(R);
// cerr << j << " " << l << " " << R << " " << r << "\n";
if (r <= n) {
s[j] = mod(s[j] + LL(R - l + 1) * (n - r + 1));
if (R == r) s[j] = mod(s[j] + P - 1);
}
l = R;
}
}
for (int i = 1; i <= n; ++i) {
s[i] = mod(s[i] + s[i - 1]);
}
for (int i = 0; i <= n; ++i) {
if (!i) {
f[i] = P - mod(LL(n) * (n - 1) / 2);
} else {
// for (int j = 1; j < i; ++j) {
// for (int l = 1; l <= n; ++l) {
// int x = j / l;
// if (!x) continue;
// int r = (j + x - 1) / x;
// if (r == l) ++r;
// if (r <= n && l < r) {
// f[i] = mod(f[i] + n - r + 1);
// }
// }
// }
for (int r = n; r >= 1; --r) {
int x = (i + r - 1) / r;
int l = (i + x - 1) / x;
f[i] = mod(f[i] + LL(r - l + 1) * x);
r = l;
}
// for (int j = 1; j <= n; ++j) {
// f[i] = mod(f[i] + (i + j - 1) / j);
// }
}
}
for (int i = 1; i <= n; ++i) {
f[i] = mod(f[i] + s[i - 1]);
}
}
void calcG() {
vector<int> vis(n + 1);
for (int c = 1; c <= n; ++c) {
g[c] = mod(mod(LL(n) * (n - 1) / 2) * c);
// BF1
// for (int j = 1; j <= n; ++j) {
// if (j % c == 0) continue;
// int x = j % c;
// g[c] = mod(g[c] + c / __gcd(x, c) - 1);
// }
// BF2
// vector<int> d1, d2;
// for (int i = 1; i * i <= c; ++i) {
// if (c % i) continue;
// d1.push_back(i);
// if (c / i != i) d2.push_back(c / i);
// }
// reverse(d1.begin(), d1.end());
// for (auto v : d2) {
// for (int i = v; i < c; i += v) if (vis[i] != c) {
// vis[i] = c;
// g[c] = mod(g[c] + LL(c / v - 1) * ((n - i) / c + 1));
// }
// }
// for (auto v : d1) {
// for (int i = v; i < c; i += v) if (vis[i] != c) {
// vis[i] = c;
// g[c] = mod(g[c] + LL(c / v - 1) * ((n - i) / c + 1));
// }
// }
auto calcg = [&](int v) {
LL res = 0;
for (auto i : d[c / v]) {
if (!mu[i]) continue;
LL var = n / v / i;
if (mu[i] == -1) var = P - var;
res = mod(res + var);
}
g[c] = mod(g[c] + (c / v - 1) * res);
};
for (auto i : d[c]) calcg(i);
}
}
int main() {
cin.tie(0)->sync_with_stdio(0);
cin >> n >> P;
mod.init(P);
initC(N - 5);
initP(N - 5);
initD(N - 5);
pn[0] = 1;
for (int i = 1; i <= n; ++i) pn[i] = mod(pn[i - 1] * n);
calcF();
calcG();
// calc ans
for (int i = 1; i <= n; ++i) f[i] = mod(f[i] + f[i - 1]);
for (int i = 1; i <= n; ++i) g[i] = mod(g[i] + g[i - 1]);
LL ans = 0;
for (int j = 0; j <= n; ++j) {
LL res = mod(binom(n, j) * pn[n - j]);
res = mod(res * fac[j]);
// for (int i = 0; i < j; ++i) {
// ans = mod(ans + (f[i] + g[j - i]) * res);
// }
res = mod(res * ((j == 0 ? 0 : f[j - 1]) + g[j]));
ans = mod(ans + res);
}
cout << ans % P << "\n";
return 0;
}