ABC 339
Table of Contents
https://atcoder.jp/contests/abc339
A. TLD
https://atcoder.jp/contests/abc339/tasks/abc339_a
B. Langton’s Takahashi
https://atcoder.jp/contests/abc339/tasks/abc339_b
C. Perfect Bus
https://atcoder.jp/contests/abc339/tasks/abc339_c
D. Synchronized Players
https://atcoder.jp/contests/abc339/tasks/abc339_d
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
ll N;
cin >> N;
vector<string> grid(N);
rep(i, N) cin >> grid[i];
vector dist(N, vector(N, vector(N, vll(N, INF))));
using P = tuple<ll, ll, ll, ll>;
queue<pair<P, ll>> que;
{
vector<pair<ll, ll>> v;
rep(i, N) rep(j, N) {
if (grid[i][j] == 'P') v.emplace_back(i, j);
}
que.emplace(P({v[0].first, v[0].second, v[1].first, v[1].second}), 0);
auto [p, _] = que.front();
auto [i, j, k, l] = p;
dist[i][j][k][l] = 0;
}
auto is_stay = [&](ll i, ll j) -> bool {
if (clamp(i, 0ll, N - 1) != i || clamp(j, 0ll, N - 1) != j) return true;
return grid[i][j] == '#';
};
vint di = {0, 1, 0, -1};
vint dj = {1, 0, -1, 0};
while (que.size()) {
auto [p, cost] = que.front();
que.pop();
auto [pi, pj, qi, qj] = p;
if (dist[pi][pj][qi][qj] < cost) continue;
rep(d, 4) {
ll npi = pi + di[d], npj = pj + dj[d];
if (is_stay(npi, npj)) {
npi = pi, npj = pj;
}
ll nqi = qi + di[d], nqj = qj + dj[d];
if (is_stay(nqi, nqj)) {
nqi = qi, nqj = qj;
}
if (cost + 1 < dist[npi][npj][nqi][nqj]) {
dist[npi][npj][nqi][nqj] = cost + 1;
que.emplace(P({npi, npj, nqi, nqj}), cost + 1);
}
}
}
ll ans = INF;
rep(i, N) rep(j, N) {
chmin(ans, dist[i][j][i][j]);
}
if (ans == INF) ans = -1;
cout << ans << endl;
}
E. Smooth Subsequence
https://atcoder.jp/contests/abc339/tasks/abc339_e
2026/1/20 segment tree の問題だとわかった状態で自力 AC
https://kenkoooo.com/atcoder/#/contest/show/76c42792-10db-491b-9486-ffc7f4f226e1?activeTab=Standings
$i$ 番目の要素までを見たときに末尾が $x$ であるような条件を満たす最長部分列の長さを $dp(i,x)$ とする。
\begin{align} dp(i, x) = \begin{cases} \max_{y \in [x-D, x+D]} dp(i-1, y) + 1 & (x = A_i) \\ dp(i-1, x) & (x \neq A_i) \end{cases} \end{align}
区間最大値を segment tree で求めることで効率的に計算できる。
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
ll N, D;
cin >> N >> D;
vll A(N);
rep(i, N) cin >> A[i];
auto op = [](ll a, ll b) -> ll {
return max(a, b);
};
auto e = []() -> ll {
return 0;
};
ll M = 5e5;
segtree<ll, op, e> seg(M + 2);
for (ll x : A) {
ll l = max(0ll, x - D);
ll r = min(M, x + D) + 1;
ll mx = seg.prod(l, r);
seg.set(x, mx + 1);
}
cout << seg.all_prod() << endl;
}
F. Product Equality
https://atcoder.jp/contests/abc339/tasks/abc339_f