ABC 450

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

G. Random Subtraction

https://atcoder.jp/contests/abc450/tasks/abc450_g