Submission #1090628

#TimeUsernameProblemLanguageResultExecution timeMemory
1090628underwaterkillerwhaleSeats (IOI18_seats)C++17
44 / 100
4110 ms155572 KiB
#include <bits/stdc++.h>
#define ll              long long
#define pii             pair<int,int>
#define pll             pair<ll,ll>
#define rep(i,m,n)      for(int i=(m); i<=(n); i++)
#define reb(i,m,n)      for(int i=(m); i>=(n); i--)
#define iter(id, v)     for(auto id : v)
#define fs              first
#define se              second
#define MP              make_pair
#define pb              push_back
#define bit(msk, i)     ((msk >> i) & 1)
#define SZ(v)           (ll)v.size()
#define ALL(v)          v.begin(),v.end()

using namespace std;

mt19937_64 rd(chrono :: steady_clock :: now ().time_since_epoch().count());
ll Rand (ll l, ll r) { return uniform_int_distribution<ll> (l, r) (rd); }

const int N = 1e6 + 7;
const int Mod = 1e9 + 2022; ///loonf mod sai
const int INF = 1e9;
const ll BASE = 137;
const int szBL = 350;

int n, m, Q;
pii seat[N];
vector<vector<int>> a;

namespace sub2 {
    pii pmn[N], pmx[N];

    int solution (int u, int v) {
        swap(seat[u], seat[v]);
        a[seat[u].fs][seat[u].se] = u;
        a[seat[v].fs][seat[v].se] = v;
        pmn[0] = MP(INF, INF);
        int res = 0;
        rep (T, 1, n * m) {
            pmn[T].fs = min (pmn[T - 1].fs, seat[T].fs);
            pmn[T].se = min (pmn[T - 1].se, seat[T].se);
            pmx[T].fs = max (pmx[T - 1].fs, seat[T].fs);
            pmx[T].se = max (pmx[T - 1].se, seat[T].se);
            if ((pmx[T].fs - pmn[T].fs + 1) * (pmx[T].se - pmn[T].se + 1) == T) ++res;
        }
        return res;
    }
}

namespace sub4 {
    struct Fenwick_Tree {
        int m;
        int fen[N];

        void init (int n) {
            m = n;
        }

        void update (int pos, int val) {
            for (; pos <= m; pos += pos &-pos) fen[pos] += val;
        }

        int get (int pos) {
            int res = 0;
            for (;pos > 0; pos -= pos & -pos) res += fen[pos];
            return res;
        }
    }BIT;

    pii pmn[N], pmx[N];
    bool ok[N], hasinit = 0;

    void init () {
        hasinit = 1;
        BIT.init(n * m);
        pmn[0] = MP(INF, INF);
        rep (T, 1, n * m) {
            pmn[T].fs = min (pmn[T - 1].fs, seat[T].fs);
            pmn[T].se = min (pmn[T - 1].se, seat[T].se);
            pmx[T].fs = max (pmx[T - 1].fs, seat[T].fs);
            pmx[T].se = max (pmx[T - 1].se, seat[T].se);
            if ((pmx[T].fs - pmn[T].fs + 1) * (pmx[T].se - pmn[T].se + 1) == T) {
                ok[T] = 1;
                BIT.update(T, 1);
            }
        }
    }

    int solution (int u, int v) {
        if (!hasinit)
            init();
        swap(seat[u], seat[v]);
        a[seat[u].fs][seat[u].se] = u;
        a[seat[v].fs][seat[v].se] = v;
        rep (T, min(u, v), max(u, v))
            if (ok[T]) BIT.update(T, -1), ok[T] = 0;
        rep (T, min(u, v), max(u, v)) {
            pmn[T].fs = min (pmn[T - 1].fs, seat[T].fs);
            pmn[T].se = min (pmn[T - 1].se, seat[T].se);
            pmx[T].fs = max (pmx[T - 1].fs, seat[T].fs);
            pmx[T].se = max (pmx[T - 1].se, seat[T].se);
            if ((pmx[T].fs - pmn[T].fs + 1) * (pmx[T].se - pmn[T].se + 1) == T) {
                ok[T] = 1;
                BIT.update(T, 1);
            }
        }
        return BIT.get(n * m);
    }
}

namespace sub3 {
    struct Segment_Tree {
        int m;
        pii st[N << 2];

        void init (int n) {
            m = n;
            rep (i, 1, n << 2) st[i] = MP(INF, 0);
        }

        void update (int id, int l, int r, int pos, int val) {
            if (l == r) {
            if (l > pos || r < pos) return;
                st[id] = MP(val, val);
                return;
            }
            int mid = l + r >> 1;
            update (id << 1, l, mid, pos, val);
            update (id << 1 | 1, mid + 1, r, pos, val);
            st[id].fs = min(st[id << 1].fs, st[id << 1 | 1].fs);
            st[id].se = max(st[id << 1].se, st[id << 1 | 1].se);
        }

        pii get (int id, int l, int r, int u, int v) {
            if (l > v || r < u) return MP(INF, 0);
            if (l >= u && r <= v) return st[id];
            int mid = l + r >> 1;
            pii lc = get (id << 1, l, mid, u, v);
            pii rc = get (id << 1 | 1, mid + 1, r, u, v);
            return MP(min(lc.fs, rc.fs), max(lc.se, rc.se));
        }

        void update (int pos, int val) {
            update (1, 1, m, pos, val);
        }
        pii get (int u, int v) {
            return get (1, 1, m, u, v);
        }
    }rw, cl;

    bool hasinit = 0;

    void init () {
        hasinit = 1;
        rw.init(n * m);
        cl.init(n * m);
        rep (T, 1, n * m) {
            rw.update(T, seat[T].fs);
            cl.update(T, seat[T].se);
        }
    }

    int solution (int u, int v) {
        if (!hasinit) init();
        swap(seat[u], seat[v]);
        rw.update (u, seat[u].fs);
        rw.update (v, seat[v].fs);
        cl.update (u, seat[u].se);
        cl.update (v, seat[v].se);
        int res = 0;
        rep (T, 1, n * m) {
            pii curR = rw.get(1, T), curC = cl.get(1, T);
            pii curmn = MP(curR.fs, curC.fs);
            pii curmx = MP(curR.se, curC.se);
            int delta = (curmx.fs - curmn.fs + 1) * (curmx.se - curmn.se + 1);
            if (delta == T) {
                ++res;
            }
            else T = delta - 1;
        }
        return res;
    }
}

namespace sub5 {

    int b[N], Val[N];

    struct Segment_Tree {
        int m;
        pii st[N << 2];
        int lz[N << 2];

        pii mer (pii lc, pii rc) {
            if (lc.fs == rc.fs) return MP(lc.fs, rc.se + lc.se);
            else if (lc.fs < rc.fs) return lc;
            else return rc;
        }

        void build (int id, int l, int r) {
            if (l == r) {
                st[id].se = 1;
                return;
            }
            int mid = l + r >> 1;
            build (id << 1, l, mid);
            build (id << 1 | 1, mid + 1, r);
            st[id] = mer(st[id << 1], st[id << 1 | 1]);
        }

        void init (int n) {
            m = n;
            build(1, 1, m);
        }

        void down (int id) {
            rep (i, id << 1, id << 1 | 1) {
                st[i].fs += lz[id];
                lz[i] += lz[id];
            }
            lz[id] = 0;
        }

        void update (int id, int l, int r, int u, int v, int val) {
            if (l > v || r < u) return;
            if (l >= u && r <= v) {
                st[id].fs += val;
                lz[id] += val;
                return;
            }
            int mid = l + r >> 1;
            down(id);
            update (id << 1, l, mid, u, v, val);
            update (id << 1 | 1, mid + 1, r, u, v, val);
            st[id] = mer(st[id << 1], st[id << 1 | 1]);
        }

        pii get (int id, int l, int r, int u, int v) {
            if (l > v || r < u) return MP(INF, 0);
            if (l >= u && r <= v) return st[id];
            down(id);
            int mid = l + r >> 1;
            return mer(get (id << 1, l, mid, u, v), get (id << 1 | 1, mid + 1, r, u, v));
        }

        void update (int u, int v, int val) {
            update (1, 1, m, u, v, val);
        }
    }ST;

    bool hasinit = 0;

    void update (int u, int v, int val) {
        if (u > v) swap (u, v);
//        cout << u <<" "<<v<<" "<<val<<"\n";
        ST.update (u, v - 1, val);
    }

    void init () {
        hasinit = 1;
        Val[0] = Val[m + 1] = m + 1;

        rep (i, 1, m) b[i] = seat[i].se, Val[b[i]] = i;
//        rep (i, 1, m) {
//            cout << Val[i]<<" ";
//        }
//        cout<<"\n";
        ST.init (m);
        rep (i, 0, m) {
            update (Val[i], Val[i + 1], 1);
        }
//        rep (i, 1, m) cout <<i<<","<< ST.get(1, 1, m, i, i).fs <<" ";
//        cout<<"\n";
//        cout << ST.st[1].se <<"\n";
    }

    int solution (int u, int v) {
        if (!hasinit)
            init ();
        vector<pii> vec;
        vec.pb({b[u] - 1, b[u]});
        vec.pb({b[u], b[u] + 1});
        vec.pb({b[v] - 1, b[v]});
        vec.pb({b[v], b[v] + 1});
        sort (ALL(vec));
        vec.resize(unique(ALL(vec)) - vec.begin());
        iter (&id, vec) update (Val[id.fs], Val[id.se], -1);
        swap(Val[b[u]], Val[b[v]]);
        swap(b[u], b[v]);
        iter (&id, vec) update (Val[id.fs], Val[id.se], 1);
//        rep (i, 1, m) cout <<i<<","<< ST.get(1, 1, m, i, i).fs <<" ";
//        cout<<"\n";
//        cout << ST.st[1].se <<"\n";
        return ST.st[1].se;
//        cout << ST.st[1].se <<"\n";
    }
}

int swap_seats (int u, int v) {
    ++u, ++v;
    if (n == 1)
        return sub5 :: solution(u, v);
    else if (n <= 1e3 && m <= 1e3)
        return sub3 :: solution(u, v);
    else if (abs(u - v) <= 1e4)
        return sub4 :: solution(u, v);
    else if (n * m <= 1e4)
        return sub2 :: solution(u, v);
}

void give_initial_chart (int _n, int _m, vector<int> _R, vector<int> _C) {
    n = _n;
    m = _m;
    rep (i, 1, n * m)
        seat[i] = MP(_R[i - 1] + 1, _C[i - 1] + 1);
    a.resize(n + 2, vector<int> (m + 2, 0));
    rep (i, 1, n * m)
        a[seat[i].fs][seat[i].se] = i;
}

void solution() {
    cin >> n >> m >> Q;
    rep (i, 1, n * m) {
        cin >> seat[i].fs >> seat[i].se;
        ++seat[i].fs;
        ++seat[i].se;
    }
    a.resize(n + 2, vector<int> (m + 2, 0));
    rep (i, 1, n * m) a[seat[i].fs][seat[i].se] = i;
    rep (i, 1, Q) {
        int u, v;
        cin >> u >> v;
        cout << swap_seats (u, v) <<"\n";
    }
}

#define file(name) freopen(name".inp","r",stdin); \
freopen(name".out","w",stdout);
//int main () {
//    file("c");
//    ios_base :: sync_with_stdio(false); cin.tie(0); cout.tie(0);
//    int num_Test = 1;
////    cin >> num_Test;
//    while (num_Test--)
//        solution();
//}
/*
no bug +8
chu y break hay return se lam hong logic
xet transition cua i va i + 1
construct ket qua
chu y truong hop : KHONG CO GI

ko làm được

hướng 1: đổi hướng làm
hướng 2: đưa ra nhận xét



2 3 2
0 0
1 0
1 1
0 1
0 2
1 2
0 5
5 0




*/

Compilation message (stderr)

seats.cpp: In member function 'void sub3::Segment_Tree::update(int, int, int, int, int)':
seats.cpp:128:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  128 |             int mid = l + r >> 1;
      |                       ~~^~~
seats.cpp: In member function 'std::pair<int, int> sub3::Segment_Tree::get(int, int, int, int, int)':
seats.cpp:138:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  138 |             int mid = l + r >> 1;
      |                       ~~^~~
seats.cpp: In member function 'void sub5::Segment_Tree::build(int, int, int)':
seats.cpp:206:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  206 |             int mid = l + r >> 1;
      |                       ~~^~~
seats.cpp: In member function 'void sub5::Segment_Tree::update(int, int, int, int, int, int)':
seats.cpp:232:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  232 |             int mid = l + r >> 1;
      |                       ~~^~~
seats.cpp: In member function 'std::pair<int, int> sub5::Segment_Tree::get(int, int, int, int, int)':
seats.cpp:243:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  243 |             int mid = l + r >> 1;
      |                       ~~^~~
seats.cpp: In function 'int swap_seats(int, int)':
seats.cpp:310:1: warning: control reaches end of non-void function [-Wreturn-type]
  310 | }
      | ^
#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...