(UPD: 2024-12-04 14:48 UTC) Judge is not working due to Cloudflare incident. (URL) We can do nothing about it, sorry. After the incident is resolved, we will grade all submissions.

Submission #603766

#TimeUsernameProblemLanguageResultExecution timeMemory
603766yuto1115Seats (IOI18_seats)C++17
100 / 100
2928 ms122916 KiB
#include "seats.h" #include "bits/stdc++.h" #define rep(i, n) for(ll i = 0; i < ll(n); ++i) #define rep2(i, s, n) for(ll i = ll(s); i < ll(n); ++i) #define rrep(i, n) for(ll i = ll(n)-1; i >= 0; --i) #define pb push_back #define eb emplace_back #define all(a) a.begin(),a.end() #define SZ(a) int(a.size()) using namespace std; using ll = long long; using P = pair<int, int>; using vi = vector<int>; using vvi = vector<vi>; using vl = vector<ll>; using vvl = vector<vl>; using vb = vector<bool>; using vvb = vector<vb>; using vp = vector<P>; using vvp = vector<vp>; using vs = vector<string>; const int inf = 1001001001; const ll linf = 1001001001001001001; template<class T> bool chmin(T &a, T b) { if (a > b) { a = b; return true; } else { return false; } } template<class T> bool chmax(T &a, T b) { if (a < b) { a = b; return true; } else { return false; } } template<class T, class S> ostream &operator<<(ostream &os, const pair<T, S> &p) { os << '{' << p.first << ", " << p.second << '}'; return os; } using S = P; const S e = {inf, 0}; S op(S a, S b) { if (a.first != b.first) return (a.first < b.first ? a : b); return {a.first, a.second + b.second}; } using F = int; const F id = 0; F composition(F g, F f) { return g + f; } S mapping(F f, S x) { return {x.first + f, x.second}; } class lazy_segtree { int n, log; vector<S> d; vector<F> lz; void all_apply(int p, F f) { d[p] = mapping(f, d[p]); if (p < n) lz[p] = composition(f, lz[p]); } void push(int p) { assert(p < n); all_apply(2 * p, lz[p]); all_apply(2 * p + 1, lz[p]); lz[p] = id; } void update(int p) { assert(p < n); d[p] = op(d[2 * p], d[2 * p + 1]); } public: lazy_segtree(const vector<S> &init = {}) { log = 0; while (1 << log < SZ(init)) ++log; n = 1 << log; d.assign(2 * n, e); rep(i, SZ(init)) d[n + i] = init[i]; for (int i = n - 1; i >= 1; --i) update(i); lz.assign(n, id); } S get(int p) { assert(0 <= p and p < n); p += n; for (int i = log; i >= 1; --i) push(p >> i); return d[p]; } S all_prod() { return d[1]; } void apply(int l, int r, F f) { assert(0 <= l and l <= r and r <= n); l += n, r += n; for (int i = log; i >= 1; --i) { if (l >> i << i != l) push(l >> i); if (r >> i << i != r) push(r >> i); } { int l2 = l, r2 = r; while (l < r) { if (l & 1) all_apply(l++, f); if (r & 1) all_apply(--r, f); l >>= 1, r >>= 1; } l = l2, r = r2; } for (int i = 1; i <= log; ++i) { if (l >> i << i != l) update(l >> i); if (r >> i << i != r) update(r >> i); } } }; int h, w; vi r, c; vvi who; lazy_segtree st; void corner_set(int i, int j, int inv = 1) { assert(0 <= i and i <= h); assert(0 <= j and j <= w); // {time, pos} vector<P> v; rep2(ni, i - 1, i + 1) rep2(nj, j - 1, j + 1) { if (ni < 0 or ni >= h or nj < 0 or nj >= w) continue; v.eb(who[ni][nj], (ni - i + 1) * 2 + (nj - j + 1)); } v.eb(h * w, -1); sort(all(v)); if (SZ(v) >= 2) { st.apply(v[0].first, v[1].first, inv); } if (SZ(v) >= 3 and v[0].second + v[1].second == 3) { st.apply(v[1].first, v[2].first, inv * 2); } if (SZ(v) >= 4) { st.apply(v[2].first, v[3].first, inv); } } void give_initial_chart(int H, int W, vi R, vi C) { h = H; w = W; r = R; c = C; who.resize(h); rep(i, h) who[i].resize(w); rep(i, h * w) who[r[i]][c[i]] = i; st = lazy_segtree(vp(h * w, {0, 1})); rep2(i, 0, h + 1) rep2(j, 0, w + 1) corner_set(i, j); // rep(i, h * w) cerr << i << ' ' << st.get(i) << endl; } int swap_seats(int a, int b) { set<P> upd; rep(i, 2) rep(j, 2) upd.insert({r[a] + i, c[a] + j}); rep(i, 2) rep(j, 2) upd.insert({r[b] + i, c[b] + j}); for (auto[i, j]: upd) corner_set(i, j, -1); swap(r[a], r[b]); swap(c[a], c[b]); swap(who[r[a]][c[a]], who[r[b]][c[b]]); assert(who[r[a]][c[a]] == a); assert(who[r[b]][c[b]] == b); for (auto[i, j]: upd) corner_set(i, j); // rep(i, h * w) cerr << i << ' ' << st.get(i) << endl; auto[mn, num] = st.all_prod(); // cerr << mn << ' ' << num << endl; assert(mn >= 4 and (~mn & 1)); return (mn == 4 ? num : 0); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...