제출 #185448

#제출 시각아이디문제언어결과실행 시간메모리
185448keko37자리 배치 (IOI18_seats)C++14
100 / 100
2766 ms141684 KiB
#include<bits/stdc++.h>

using namespace std;

typedef long long llint;
typedef pair <llint, int> pi;

const int MAXN = 1000005;
const llint INF = 1000000000000000000LL;
const int BIG = 1000000000;

int n, m;
vector <int> r, c;
vector < vector <int> > v;
llint a[MAXN], b[MAXN];
int dx[4] = {0, 0, 1, 1};
int dy[4] = {0, 1, 0, 1};

pi t[MAXN * 2]; llint prop[MAXN * 2];

pi spoji (pi a, pi b) {
    if (a.first < b.first) return a;
    if (a.first > b.first) return b;
    return {a.first, a.second + b.second};
}

void tour_init () {
    for (int i = n*m; i < 2*n*m; i++) t[i].second = 1;
    for (int i = 0; i < n*m; i++) t[i] = spoji(t[i<<1], t[i<<1|1]);
}

void build (int p) {
    while (p > 1) p >>= 1, t[p] = spoji(t[p<<1], t[p<<1|1]), t[p].first += prop[p];
}

void upd(int l, int r, int value) {
    l += n*m, r += n*m;
    int l0 = l, r0 = r;
    for (; l < r; l >>= 1, r >>= 1) {
        if (l&1) t[l].first += value, prop[l] += value, l++;
        if (r&1) r--, t[r].first += value, prop[r] += value;
    }
    build(l0);
    if (r0 - 1 != l0) build(r0 - 1);
}

void two_by_two (int x, int y, int d) {
    int w[4] = {v[x][y], v[x][y + 1], v[x + 1][y], v[x + 1][y + 1]};
    sort(w, w + 4);
    if (w[0] < w[1]) upd(w[0], w[1], d);
    if (w[2] < w[3]) upd(w[2], w[3], d * BIG);
}

void give_initial_chart (int N, int M, vector <int> R, vector <int> C) {
    n = N; m = M; r = R; c = C;
    vector <int> e(m + 2, n*m);
    for (int i = 0; i < n + 2; i++) v.push_back(e);
    for (int i = 0; i < n * m; i++) {
        v[R[i] + 1][C[i] + 1] = i;
    }
    tour_init();
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            two_by_two(i, j, 1);
        }
    }
}

int swap_seats (int a, int b) {
    vector <pi> u;
    for (int i = 0; i < 4; i++) u.push_back({r[a] + dx[i], c[a] + dy[i]});
    for (int i = 0; i < 4; i++) u.push_back({r[b] + dx[i], c[b] + dy[i]});
    sort(u.begin(), u.end());
    u.erase(unique(u.begin(), u.end()), u.end());

    for (auto p : u) two_by_two(p.first, p.second, -1);
    swap(v[r[a] + 1][c[a] + 1], v[r[b] + 1][c[b] + 1]);
    swap(r[a], r[b]);
    swap(c[a], c[b]);
    for (auto p : u) two_by_two(p.first, p.second, 1);

    if (t[1].first > 4) return 0;
    return t[1].second;
}
#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...