AtCoder Beginner Contest 176 感想
うぉ~~Highest付近まで戻ってきたぞ!
— scol (@scol_kp) 2020年8月22日
scolさんのAtCoder Beginner Contest 176での成績:426位
パフォーマンス:1868相当
レーティング:1537→1575 (+38) :)#AtCoder #ABC176 https://t.co/txxqqpSt4P
AtCoderは好調。こどふぉは不調。世界のバランスは保たれている。
A - Takoyaki
リンク: https://atcoder.jp/contests/abc176/submissions/16096210提出コード
void solve() {
ll N, X, T;
cin >> N >> X >> T;
prints()((N + X - 1) / X * T);
}
B - Multiple of 9
問題名を見て一瞬冷や汗をかいた(みんなのトラウマ)。
リンク: https://atcoder.jp/contests/abc176/submissions/16100219提出コード
void solve() {
string S;
cin >> S;
ll sum = 0;
for (auto c : S) {
sum += c - '0';
}
prints()(sum % 9 == 0 ? "Yes" : "No");
}
C - Step
リンク: https://atcoder.jp/contests/abc176/submissions/16106741提出コード
void solve() {
ll N;
cin >> N;
Vl A(N);
for (ll i = 0; i < N; i++) {
cin >> A[i];
}
ll mx = 0;
ll ans = 0;
for (ll i = 0; i < N; i++) {
ans += max(mx - A[i], 0ll);
chmax(mx, A[i]);
}
prints()(ans);
}
D - Wizard in Maze
ダイクストラだろうとはすぐに思ったけど、計算量は係数がかなり大きめの なので一瞬ためらった。 でも、順位表を見ると光速でACしてる人がたくさんいたので安心して提出した。
実際、実行時間は 249ms でかなり余裕だった。
[追記]
解説によれば で解けるらしいです(笑)
リンク: https://atcoder.jp/contests/abc176/submissions/16123764提出コード
using Pos = array<ll, 2>;
int cell[1010][1010];
int dp[1010][1010];
void solve() {
ll H, W;
cin >> H >> W;
Pos s, t;
cin >> s[0] >> s[1];
cin >> t[0] >> t[1];
--s[0], --s[1], --t[0], --t[1];
for (ll i = 0; i < H; i++) {
string a;
cin >> a;
for (ll j = 0; j < W; j++) {
cell[i][j] = a[j] == '#';
}
}
for (ll i = 0; i < H; i++) {
for (ll j = 0; j < W; j++) {
dp[i][j] = I_INF;
}
}
using Tup = tuple<int, int, int>;
priority_queue<Tup, vector<Tup>, greater<Tup>> pq;
pq.emplace(0, s[0], s[1]);
dp[s[0]][s[1]] = 0;
constexpr Pos steps[4] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
while (!pq.empty()) {
auto [c, x, y] = pq.top();
pq.pop();
if (c > dp[x][y]) continue;
for (ll i = 0; i < 4; i++) {
int nx = x + steps[i][0];
int ny = y + steps[i][1];
int nc = c;
if (!(nx >= 0 && nx < H && ny >= 0 && ny < W)) continue;
if (cell[nx][ny] == 1) continue;
if (dp[nx][ny] <= nc) continue;
dp[nx][ny] = nc;
pq.emplace(nc, nx, ny);
}
for (ll i = 0; i < 5; i++) {
for (ll j = 0; j < 5; j++) {
int nx = x + i - 2;
int ny = y + j - 2;
int nc = c + 1;
if (!(nx >= 0 && nx < H && ny >= 0 && ny < W)) continue;
if (cell[nx][ny] == 1) continue;
if (dp[nx][ny] <= nc) continue;
dp[nx][ny] = nc;
pq.emplace(nc, nx, ny);
}
}
}
int ans = dp[t[0]][t[1]];
if (ans == I_INF) {
prints()(-1);
}
else {
prints()(ans);
}
}
E - Bomber
爆破対象の位置を とする。 爆弾を にセットしたとき、 を満たす の個数を 、 を満たす の個数を 、 かつ を満たす の個数 とすると、爆破される個数は で求められる。 ただし、 の大きさは高々1。
を固定したとき、 としては を最も大きくするものを選ぶのが最適。 各 に対する の値をセグ木で管理しながら を動かして大域解を求める。
計算量は僕の実装だと 。でも係数がかなり大きくて実行時間は 1190 ms だった。
提出したら 3/130
... とか表示されてびっくりした。こどふぉか?
リンク: https://atcoder.jp/contests/abc176/submissions/16134198提出コード
template <class T, class Op>
class SegmentTree {
private:
const Op op;
const T id;
std::vector<T> vec;
int sz;
public:
explicit SegmentTree(int n, Op op, T id) noexcept
: op(op), id(id) {
sz = 1;
while (sz < n) sz <<= 1;
vec.assign(sz * 2, id);
}
explicit SegmentTree(const std::vector<T>& vec, Op op, T id) noexcept
: op(op), id(id) {
int n = vec.size();
sz = 1;
while (sz < n) sz <<= 1;
this->vec.assign(sz * 2, id);
set_array(vec);
}
void set_value(int idx, T val) noexcept {
vec[idx + sz] = val;
}
template <class RandomIt>
void set_array(RandomIt _begin, RandomIt _end) noexcept {
std::copy(_begin, _end, vec.begin() + sz);
}
void set_array(const std::vector<T>& vec) noexcept {
set_array(vec.begin(), vec.end());
}
void build() noexcept {
for (int i = sz - 1; i > 0; i--) {
vec[i] = op(vec[i * 2], vec[i * 2 + 1]);
}
}
void update(int idx, T val) noexcept {
idx += sz;
vec[idx] = val;
for (idx >>= 1; idx > 0; idx >>= 1) {
vec[idx] = op(vec[idx * 2], vec[idx * 2 + 1]);
}
}
// Query [l, r)
T query(int l, int r) const noexcept {
T l_val = id, r_val = id;
l += sz, r += sz - 1;
for (; l <= r; l >>= 1, r >>= 1) {
if (l & 1) l_val = op(l_val, vec[l++]);
if (!(r & 1)) r_val = op(r_val, vec[r--]);
}
return op(l_val, r_val);
}
const T& operator[](int idx) const noexcept {
return vec[idx + sz];
}
void reset() noexcept {
std::fill(vec.begin(), vec.end(), id);
}
};
void solve() {
ll H, W, M;
cin >> H >> W >> M;
map<ll, Vi> xs;
map<ll, ll> ys;
for (ll i = 0; i < M; i++) {
int a, b;
cin >> a >> b;
--a, --b;
xs[a].emplace_back(b);
++ys[b];
}
ll sz = (ll)ys.size();
map<ll, ll> pos;
Vl vals;
for (auto [a, b] : ys) {
vals.emplace_back(b);
pos[a] = (ll)vals.size() - 1;
}
auto op = [](ll l, ll r) { return max(l, r); };
SegmentTree seg(sz, op, 0ll);
for (ll i = 0; i < sz; i++) {
seg.set_value(i, vals[i]);
}
seg.build();
ll ans = 0;
for (const auto& [a, vec] : xs) {
ll t = (ll)vec.size();
for (auto b : vec) {
ll idx = pos[b];
ll v = seg[idx];
seg.update(idx, v - 1);
}
chmax(ans, t + seg.query(0, sz));
for (auto b : vec) {
ll idx = pos[b];
ll v = seg[idx];
seg.update(idx, v + 1);
}
}
prints()(ans);
}
F - Brave CHAIN
9000人中18人しか解けてませんけど(笑)。ABCにAGCの問題を出すのやめてください!!