ABC 450
Table of Contents
https://atcoder.jp/contests/abc450
A. 3,2,1,GO
https://atcoder.jp/contests/abc450/tasks/abc450_a
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
ll N;
cin >> N;
vint ans(N);
iota(all(ans), 1);
reverse(all(ans));
rep(i, N) {
if (i != 0) cout << ',';
cout << ans[i];
}
cout << endl;
}
B. Split Ticketing
https://atcoder.jp/contests/abc450/tasks/abc450_b
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
ll N;
cin >> N;
vvll C(N, vll(N));
rep(i, N) {
rep2(j, i + 1, N) {
ll c;
cin >> c;
C[i][j] = c;
}
}
int ok = 0;
rep(a, N) rep2(b, a + 1, N) rep2(c, b + 1, N) {
if (C[a][b] + C[b][c] < C[a][c]) ok = 1;
}
yesno(ok);
}
C. Puddles
https://atcoder.jp/contests/abc450/tasks/abc450_c
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
ll H, W;
cin >> H >> W;
vector<string> grid(H);
rep(i, H) cin >> grid[i];
dsu uf(H * W + 1);
vint di = {0, 1, 0, -1};
vint dj = {1, 0, -1, 0};
int ban = H * W;
rep(i, H) {
rep(j, W) {
if (grid[i][j] == '#') continue;
ll now = i * W + j;
if (i == 0 || j == 0 || i == H - 1 || j == W - 1) uf.merge(now, ban);
rep(d, 4) {
ll ni = i + di[d], nj = j + dj[d];
if (clamp(ni, 0ll, H - 1) != ni || clamp(nj, 0ll, W - 1) != nj) continue;
if (grid[ni][nj] == '.') uf.merge(now, ni * W + nj);
}
}
}
set<int> ans;
rep(i, H) {
rep(j, W) {
ll now = i * W + j;
if (grid[i][j] == '.' && !uf.same(now, ban)) ans.insert(uf.leader(now));
}
}
cout << ans.size() << endl;
}
D. Minimize Range
https://atcoder.jp/contests/abc450/tasks/abc450_d
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
ll N, K;
cin >> N >> K;
vll A(N);
rep(i, N) cin >> A[i];
rep(i, N) A[i] %= K;
sort(all(A));
deque<ll> deq;
rep(i, N) deq.pb(A[i]);
ll ans = deq.back() - deq.front();
rep(i, N) {
deq.pb(deq.front() + K);
deq.pop_front();
chmin(ans, deq.back() - deq.front());
}
cout << ans << endl;
}
E. Fibonacci String
https://atcoder.jp/contests/abc450/tasks/abc450_e
2026/3/22 解説 AC
$S_k$ の $r$ 文字目に含まれる $c$ の数をメモ化再帰で求めるのがいいと思ったが逆に遅くなった。 $S_k$ に含まれる $c$ の数を事前計算しておくとメモ化を使わなくてもうまく行った。
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
string X, Y;
cin >> X >> Y;
// xcnt[i][c]: X の [0, i) の範囲にある文字 c の個数
// ycnt[i][c]: Y の [0, i) の範囲にある文字 c の個数
ll xsz = X.size(), ysz = Y.size();
vvll xcnt(xsz + 1, vll(26)), ycnt(ysz + 1, vll(26));
rep(i, xsz) {
int c = X[i] - 'a';
xcnt[i + 1][c]++;
}
rep(c, 26) rep(i, xsz) xcnt[i + 1][c] += xcnt[i][c];
rep(i, ysz) {
int c = Y[i] - 'a';
ycnt[i + 1][c]++;
}
rep(c, 26) rep(i, ysz) ycnt[i + 1][c] += ycnt[i][c];
// len[k]: S_k の長さ
vll len(100);
int cnt = 3;
{
len[1] = xsz;
len[2] = ysz;
ll b = ysz, a = xsz;
while (b + a <= (ll)2e18 + 5) {
ll c = b + a;
a = b;
b = c;
len[cnt] = c;
cnt++;
}
}
// scnt[k][c]: S_k に含まれる文字 c の個数
vvll scnt(cnt + 1, vll(26));
rep(i, 26) scnt[1][i] = xcnt[xsz][i];
rep(i, 26) scnt[2][i] = ycnt[ysz][i];
rep2(k, 3, cnt + 1) {
rep(c, 26) {
scnt[k][c] = scnt[k - 1][c] + scnt[k - 2][c];
}
}
// dfs(index, r, c): S_k の [0, r) の範囲にある文字 c の個数
auto dfs = [&](auto dfs, ll index, ll r, ll c) -> ll {
if (index == 0) return 0;
if (index == 1) return xcnt[r][c];
if (index == 2) return ycnt[r][c];
ll fr = len[index - 1];
if (r <= fr) {
return dfs(dfs, index - 1, r, c);
}
return scnt[index - 1][c] + dfs(dfs, index - 2, r - fr, c);
};
auto cal = [&]() -> void {
ll L, R;
char C;
cin >> L >> R >> C;
int si = 0;
while (len[si] < R) si++;
ll c = C - 'a';
cout << dfs(dfs, si, R, c) - dfs(dfs, si, L - 1, c) << endl;
};
ll Q;
cin >> Q;
while (Q--) {
cal();
}
}
F. Strongly Connected 2
https://atcoder.jp/contests/abc450/tasks/abc450_f