Submission #1365282

#TimeUsernameProblemLanguageResultExecution timeMemory
1365282retardeSeats (IOI18_seats)C++20
100 / 100
2021 ms172676 KiB
#include "seats.h"
#include <bits/stdc++.h>
using namespace std;

const long long big = 1e7;
class Segtree {
    private:
    struct Node {
        long long mn, c;
    };
    long long n; vector<Node> seg; vector<long long> lazy;
    Node merge(Node &a, Node &b) {
        if (a.mn < b.mn) return a;
        if (a.mn > b.mn) return b;
        return Node({a.mn, a.c + b.c});
    }
    public:
    Segtree() {}
    Segtree(int n) {
        seg.resize(4 * n); lazy.resize(4 * n);
        this->n = n;
        build(1, 0, n - 1);
    }
    void build(int i, int l, int r) {
        lazy[i] = 0;
        if (l == r) {
            seg[i] = {0, 1};
            return;
        }
        int mid = (l + r) / 2;
        build(i * 2, l, mid); build(i * 2 + 1, mid + 1, r);
        seg[i] = merge(seg[i * 2], seg[i * 2 + 1]);
    }
    void push(int i, int l, int r) {
        if (!lazy[i]) return;
        seg[i].mn += lazy[i];
        if (l != r) {
            lazy[i * 2] += lazy[i];
            lazy[i * 2 + 1] += lazy[i];
        }
        lazy[i] = 0;
    }
    void upd(int i, int l, int r, int ql, int qr, long long qv) {
        push(i, l, r);
        if (r < ql || qr < l) return;
        if (ql <= l && r <= qr) {
            lazy[i] += qv;
            push(i, l, r);
            return;
        }
        int mid = (l + r) / 2;
        upd(i * 2, l, mid, ql, qr, qv);
        upd(i * 2 + 1, mid + 1, r, ql, qr, qv);
        seg[i] = merge(seg[i * 2], seg[i * 2 + 1]);
    }
    void update(int ql, int qr, int qv) {
        upd(1, 0, n - 1, ql, qr, qv);
    }
    long long query() {
        return seg[1].c;
    }
};

int h, w;
vector<vector<int>> arr; int r[1000005], c[1000005];
Segtree st;

int get(int i, int j) {
    if (i < 0 || j < 0) return 1e9;
    if (i >= h || j >= w) return 1e9;
    return arr[i][j];
}

// lexicographical min of {cnt3, cnt1}
// score = cnt3 * big + cnt1

void cont(pair<int, int> i, pair<int, int> j, int d) {
    if (i > j) swap(i, j);
    int a1 = i.first, a2 = j.first, b1 = i.second, b2 = j.second;
    vector<int> tmp({get(a1, b1), get(a1, b2), get(a2, b1), get(a2, b2)});
    sort(tmp.begin(), tmp.end());
    if (tmp[1] != 1e9) {
        st.update(tmp[0], tmp[1] - 1, d);
    } else {
        st.update(tmp[0], h*w-1, d);
    }
    if (tmp[2] != 1e9) {
        if (tmp[3] != 1e9) {
            st.update(tmp[2], tmp[3] - 1, d*big);
        } else {
            st.update(tmp[2], h*w-1, d*big);
        }
    }
}

void give_initial_chart(int H, int W, std::vector<int> R, std::vector<int> C) {
    w = W; h = H; st = Segtree(H*W);
    arr.assign(H, vector<int>(W));
    for (int i = 0; i < H*W; i++) {
        c[i] = C[i];
        r[i] = R[i];
        arr[r[i]][c[i]] = i;
    }
    for (int i = 0; i <= H; i++) {
        for (int j = 0; j <= W; j++) {
            cont({i, j}, {i - 1, j - 1}, 1);
        }
    }
}

int swap_seats(int a, int b) {
    pair<int, int> x = {r[a], c[a]}, y = {r[b], c[b]};
    cont(x, {x.first-1,x.second-1}, -1);
    cont(x, {x.first-1,x.second+1}, -1);
    cont(x, {x.first+1,x.second-1}, -1);
    cont(x, {x.first+1,x.second+1}, -1);
    
    cont(y, {y.first-1,y.second-1}, -1);
    cont(y, {y.first-1,y.second+1}, -1);
    cont(y, {y.first+1,y.second-1}, -1);
    cont(y, {y.first+1,y.second+1}, -1);

    swap(arr[x.first][x.second], arr[y.first][y.second]);
    swap(r[a], r[b]); swap(c[a], c[b]);

    cont(x, {x.first-1,x.second-1}, 1);
    cont(x, {x.first-1,x.second+1}, 1);
    cont(x, {x.first+1,x.second-1}, 1);
    cont(x, {x.first+1,x.second+1}, 1);
    
    cont(y, {y.first-1,y.second-1}, 1);
    cont(y, {y.first-1,y.second+1}, 1);
    cont(y, {y.first+1,y.second-1}, 1);
    cont(y, {y.first+1,y.second+1}, 1);

    return st.query();
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...