제출 #547362

#제출 시각아이디문제언어결과실행 시간메모리
547362dxz05자리 배치 (IOI18_seats)C++14
37 / 100
4069 ms84528 KiB
#pragma GCC optimize("Ofast,O2,O3")
#pragma GCC target("avx,avx2")

#include "seats.h"
#include <bits/stdc++.h>

using namespace std;

struct SegTree {
    struct node {
        int min;
        int max;

        node(int a, int b) {
            min = a;
            max = b;
        }

        node() {};
    };

    inline node combine(node a, node b) {
        return node(min(a.min, b.min), max(a.max, b.max));
    }

    int size = 1;
    vector<node> tree;
    vector<int> arr;

    inline void build(int v, int tl, int tr) {
        if (tl == tr) {
            tree[v] = node(arr[tl], arr[tl]);
            return;
        }
        int tm = (tl + tr) >> 1;

        build(v + v, tl, tm);
        build(v + v + 1, tm + 1, tr);

        tree[v] = combine(tree[v + v], tree[v + v + 1]);
    }

    inline void init(vector<int> &vec) {
        size = vec.size();
        arr = vec;
        tree.resize(size * 4 + 5);
        build(1, 0, size - 1);
    }

    inline void update(int v, int tl, int tr, int pos, int val) {
        if (tl == tr) {
            tree[v] = node(val, val);
            return;
        }
        int tm = (tl + tr) >> 1;
        if (pos <= tm) update(v + v, tl, tm, pos, val);
        else
            update(v + v + 1, tm + 1, tr, pos, val);

        tree[v] = combine(tree[v + v], tree[v + v + 1]);
    }

    inline void update(int pos, int val) {
        update(1, 0, size - 1, pos, val);
    }

    inline void tree_swap(int a, int b) {
        update(b, arr[a]);
        update(a, arr[b]);
        swap(arr[a], arr[b]);
    }

    inline node get(int v, int tl, int tr, int l, int r) {
        if (l <= tl && tr <= r) return tree[v];
        if (tl > r || tr < l) return node(1e9, -1e9);
        int tm = (tl + tr) >> 1;
        return combine(get(v + v, tl, tm, l, r), get(v + v + 1, tm + 1, tr, l, r));
    }

    inline node get(int l, int r) {
        return get(1, 0, size - 1, l, r);
    }

    inline node get(int i) {
        return get(0, i);
    }

    inline int get_diff(int i) {
        node p = get(1, 0, size - 1, 0, i);
        return p.max - p.min + 1;
    }

};

int N;
int H, W;
vector<int> row, col;
SegTree A, B;

int ans = 0;
vector<int> good;

void give_initial_chart(int _H, int _W, vector<int> _R, vector<int> _C) {
    H = _H;
    W = _W;
    row = _R;
    col = _C;

    A.init(row);
    B.init(col);

    N = H * W;
    good.resize(N);
    ans = 0;

    for (int i = 0; i < N; i++){
        good[i] = A.get_diff(i) * B.get_diff(i) == i + 1;
        ans += good[i];
    }
}

int swap_seats(int a, int b) {
    if (a > b) swap(a, b);

    A.tree_swap(a, b);
    B.tree_swap(a, b);
    swap(row[a], row[b]);
    swap(col[a], col[b]);

    if (H <= 1000 && W <= 1000){
        ans = 0;
        int i = 0;

        while (i < N) {
            int val = A.get_diff(i) * B.get_diff(i);

            if (val == i + 1) {
                i++;
                ans++;
            } else {
                i = val - 1;
            }
        }

        return ans;
    } else {
        int mnh = A.get(a).min, mxh = A.get(a).max, mnw = B.get(a).min, mxw = B.get(a).max;
        for (int i = a; i <= b; i++){
            mnh = min(mnh, row[i]);
            mxh = max(mxh, row[i]);
            mnw = min(mnw, col[i]);
            mxw = max(mxw, col[i]);            

            ans -= good[i];
            good[i] = (mxh - mnh + 1) * (mxw - mnw + 1) == i + 1;
            ans += good[i];
        }

        return ans;
    }

    return -1;
}
#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...