This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "seats.h"
#include <bits/stdc++.h>
using namespace std;
constexpr int inf = 6 << 22;
template <typename T>
struct segment_tree {
int n;
vector<T> s;
segment_tree() {
}
segment_tree(int _n) {
n = 2 << __lg(_n);
s.resize(2 * n - 1);
}
segment_tree(vector<T> &a) : segment_tree(a.size()) {
for (int i = 0; i < a.size(); i++) {
s[i + n - 1] = a[i];
}
for (int i = n - 2; i >= 0; i--) {
s[i] = s[i * 2 + 1] + s[i * 2 + 2];
}
}
void modify(int p, int l, int r, int x, const T &v) {
if (l + 1 == r) {
s[p] = v;
return;
}
int m = (l + r + 1) / 2;
if (x < m) {
modify(p * 2 + 1, l, m, x, v);
} else {
modify(p * 2 + 2, m, r, x, v);
}
s[p] = s[p * 2 + 1] + s[p * 2 + 2];
}
void modify(int x, const T &v) {
modify(0, 0, n, x, v);
}
T range_query(int p, int l, int r, int L, int R) {
if (R <= l || r <= L) {
return T();
}
if (L <= l && r <= R) {
return s[p];
}
int m = (l + r + 1) / 2;
return range_query(p * 2 + 1, l, m, L, R) + range_query(p * 2 + 2, m, r, L, R);
}
T range_query(int l, int r) {
return range_query(0, 0, n, l, r);
}
};
struct node {
int xmin, xmax, ymin, ymax;
node() {
xmin = inf;
xmax = -inf;
ymin = inf;
ymax = -inf;
}
node(int a, int b, int c, int d) {
xmin = a;
xmax = b;
ymin = c;
ymax = d;
}
};
node operator+(node a, node b) {
node c;
c.xmin = min(a.xmin, b.xmin);
c.xmax = max(a.xmax, b.xmax);
c.ymin = min(a.ymin, b.ymin);
c.ymax = max(a.ymax, b.ymax);
return c;
}
int N, M, ans, T;
vector<int> A, B, xmax, xmin, ymax, ymin;
int f(int k) {
return (xmax[k] - xmin[k] + 1) * (ymax[k] - ymin[k] + 1) == k;
}
segment_tree<node> st;
void give_initial_chart(int H, int W, std::vector<int> R, std::vector<int> C) {
N = H, M = W;
A = R, B = C;
xmax.resize(N * M + 1, -1);
xmin.resize(N * M + 1, N);
ymax.resize(N * M + 1, -1);
ymin.resize(N * M + 1, M);
for (int i = 0; i < N * M; i++) {
xmax[i + 1] = max(xmax[i], A[i]);
xmin[i + 1] = min(xmin[i], A[i]);
ymax[i + 1] = max(ymax[i], B[i]);
ymin[i + 1] = min(ymin[i], B[i]);
ans += f(i + 1);
}
vector<node> t(N * M);
for (int i = 0; i < N * M; i++) {
t[i] = {A[i], A[i], B[i], B[i]};
}
st = segment_tree<node>(t);
}
int swap_seats(int a, int b) {
swap(A[a], A[b]);
swap(B[a], B[b]);
if (abs(a - b) <= 100000) {
for (int i = min(a, b); i <= max(a, b); i++) {
ans -= f(i + 1);
xmax[i + 1] = max(xmax[i], A[i]);
xmin[i + 1] = min(xmin[i], A[i]);
ymax[i + 1] = max(ymax[i], B[i]);
ymin[i + 1] = min(ymin[i], B[i]);
ans += f(i + 1);
}
return ans;
}
int ans = 1;
st.modify(a, {A[a], A[a], B[a], B[a]});
st.modify(b, {A[b], A[b], B[b], B[b]});
int s = 0, L = B[0], R = B[0], U = A[0], D = A[0];
while (L != 0 || R != M - 1 || U != 0 || D != N - 1) {
int lo = s + 1, hi = N * M - 1;
while (lo < hi) {
int mi = (lo + hi) / 2;
node t = st.range_query(s + 1, mi + 1);
if (t.xmin < U || t.xmax > D || t.ymin < L || t.ymax > R) {
hi = mi;
} else {
lo = mi + 1;
}
}
if ((D - U + 1) * (R - L + 1) == lo) {
ans++;
}
U = min(U, A[lo]);
D = max(D, A[lo]);
L = min(L, B[lo]);
R = max(R, B[lo]);
s = lo;
}
return ans;
}
Compilation message (stderr)
seats.cpp: In instantiation of 'segment_tree<T>::segment_tree(std::vector<_Tp>&) [with T = node]':
seats.cpp:100:30: required from here
seats.cpp:16:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<node, std::allocator<node> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
16 | for (int i = 0; i < a.size(); i++) {
| ~~^~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |