ABC 227
Table of Contents
https://atcoder.jp/contests/abc227
A. Last Card
https://atcoder.jp/contests/abc227/tasks/abc227_a
B. KEYENCE building
https://atcoder.jp/contests/abc227/tasks/abc227_b
C. ABC conjecture
https://atcoder.jp/contests/abc227/tasks/abc227_c
D. Project Planning
https://atcoder.jp/contests/abc227/tasks/abc227_d
E. Swap
https://atcoder.jp/contests/abc227/tasks/abc227_e
F. Treasure Hunting
https://atcoder.jp/contests/abc227/tasks/abc227_f
G. Divisors of Binomial Coefficient
https://atcoder.jp/contests/abc227/tasks/abc227_g
2026/2/22 解説 AC
using Int = unsigned long long int;
Int kth_root(Int x, Int k) {
assert(k != 0);
if (x == 1 || k == 1) return x;
Int l = 0, r = x;
while (r - l > 1) {
Int m = (r - l) / 2 + l;
Int t = x;
rep(i, k) t /= m;
if (1 > t) {
r = m;
} else {
l = m;
}
}
return l;
};
// 平方根
Int isqrt(Int x) {
return kth_root(x, 2);
};
vll cal_lpf(ll N) {
vll lpf(N + 1, -1);
vll primes;
rep2(d, 2, N + 1) {
if (lpf[d] < 0) {
lpf[d] = d;
primes.push_back(d);
}
for (ll p : primes) {
if (p * d > N || p > lpf[d]) break;
lpf[p * d] = p;
}
}
return lpf;
}
// x を素因数分解する
// pair = <prime, cnt>
vector<pair<ll, ll>> factorize(vll& lpf, ll x) {
vector<pair<ll, ll>> facs;
{
while (x != 1) {
ll p = lpf[x];
ll cnt = 0;
while (x % p == 0) {
x /= p;
cnt++;
}
facs.push_back({p, cnt});
}
}
return facs;
}
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
ll N, K;
cin >> N >> K;
ll M = max(K + 1, (ll)isqrt(N) + 1);
vll lpf = cal_lpf(M), primes;
rep2(i, 2, M) {
if (lpf[i] == i) primes.push_back(i);
}
ll psz = primes.size();
vll cnt(psz);
rep2(k, 2, K + 1) {
auto ps = factorize(lpf, k);
for (auto [p, num] : ps) {
int i = lower_bound(all(primes), p) - primes.begin();
cnt[i] -= num;
}
}
ll L = N - K + 1, R = N;
vll A(R - L + 1);
iota(all(A), L);
for (ll p : primes) {
for (ll j = ceil(L, p) * p; j <= R; j += p) {
ll x = A[j - L];
ll num = 0;
while (x % p == 0) {
num++;
x /= p;
}
int i = lower_bound(all(primes), p) - primes.begin();
cnt[i] += num;
A[j - L] = x;
}
}
mint ans = 1;
for (ll x : cnt) ans *= x + 1;
for (ll x : A) {
if (x != 1) ans *= 2;
}
cout << ans.val() << endl;
}