Submission #423132

#TimeUsernameProblemLanguageResultExecution timeMemory
423132jtnydv25Seats (IOI18_seats)C++17
33 / 100
1497 ms90748 KiB
#include "seats.h" #include <bits/stdc++.h> using namespace std; #define ll long long #define pii pair<int, int> #define all(c) ((c).begin()), ((c).end()) #define sz(x) ((int)(x).size()) #ifdef LOCAL #include <print.h> #else #define trace(...) #define endl '\n' #endif // min, min_count segtree struct Data{ int mn, mncnt; Data() : mn(0), mncnt(1){} Data(int mn, int mncnt) : mn(mn), mncnt(mncnt){} }; Data merge(const Data & A, const Data & B){ Data ret; ret.mn = min(A.mn, B.mn); ret.mncnt = (A.mn == ret.mn ? A.mncnt : 0) + (B.mn == ret.mn ? B.mncnt : 0); return ret; } struct segtree{ vector<Data> tree; vector<int> lazy; int n; segtree(){} segtree(vector<int> vals) : n(vals.size()){ tree.resize(4 * n); lazy.resize(4 * n); function<void(int, int, int)> make = [&](int s, int e, int ind){ if(s == e){ tree[ind] = Data(vals[s], 1); return; } int mid = (s + e) >> 1; make(s, mid, 2 * ind); make(mid + 1, e, 2 * ind + 1); tree[ind] = merge(tree[2 * ind], tree[2 * ind + 1]); }; make(0, n - 1, 1); } void push(int s, int e, int ind){ int l = lazy[ind]; if(l == 0) return; tree[ind].mn += l; if(s != e){ lazy[2 * ind] += l; lazy[2 * ind + 1] += l; } lazy[ind] = 0; } void add(int L, int R, int v, int s, int e, int ind){ push(s, e, ind); if(L > e || s > R) return; if(s >= L && e <= R){ lazy[ind] += v; push(s, e, ind); return; } int mid = (s + e) >> 1; add(L, R, v, s, mid, 2 * ind); add(L, R, v, mid + 1, e, 2 * ind + 1); tree[ind] = merge(tree[2 * ind], tree[2 * ind + 1]); } void add(int L, int R, int v){ R = min(R, n - 1); if(L > R) return; add(L, R, v, 0, n - 1, 1); } }; int H, W; vector<int> R, C; vector<vector<int>> when; segtree st; vector<int> init; void add_contribution(int i, int j, int k, bool flag = 0){ int mint = H * W, second_min = H * W; for(int _i : {i, i + 1}) for(int _j : {j, j + 1}){ if(when[_i][_j] < mint){ second_min = mint; mint = when[_i][_j]; } else if(when[_i][_j] < second_min) second_min = when[_i][_j]; } if(!flag) st.add(mint, second_min - 1, k); else if(mint < second_min){ init[mint]++; if(second_min < H * W) init[second_min]--; } } void give_initial_chart(int h, int w, vector<int> r, vector<int> c){ H = h; W = w; R = r; C = c; when.assign(H + 2, vector<int>(W + 2, H * W)); init.resize(H * W); for(int i = 0; i < H * W; i++){ R[i]++; C[i]++; when[R[i]][C[i]] = i; } for(int i = 0; i <= H; i++){ for(int j = 0; j <= W; j++){ add_contribution(i, j, 1, true); } } for(int i = 1; i < H * W; i++) init[i] += init[i - 1]; st = segtree(init); } int swap_seats(int a, int b) { set<pair<int, int>> changes; int u = R[a], v = C[a]; for(int i : {u - 1, u}) for(int j : {v - 1, v}) changes.insert({i, j}); u = R[b], v = C[b]; for(int i : {u - 1, u}) for(int j : {v - 1, v}) changes.insert({i, j}); for(auto it : changes) add_contribution(it.first, it.second, -1); when[R[b]][C[b]] = a; when[R[a]][C[a]] = b; swap(R[a], R[b]); swap(C[a], C[b]); for(auto it : changes) add_contribution(it.first, it.second, 1); Data D = st.tree[1]; assert(D.mn == 4); return D.mncnt; }
#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...