Submission #218806

# Submission time Handle Problem Language Result Execution time Memory
218806 2020-04-02T18:46:58 Z Vimmer Matching (COCI20_matching) C++14
5 / 110
37 ms 57472 KB
#include <bits/stdc++.h>

//#pragma GCC optimize("unroll-loops")
//#pragma GCC optimize("-O3")
//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("fast-math")
//#pragma GCC optimize("no-stack-protector")

#define F first
#define S second
#define sz(x) int(x.size())
#define pb push_back
#define N 100001

using namespace std;

int x[N], y[N], a[N][2], b[N], n, xr[N], yr[N];

set <int> tx[N * 4], alone;

set <pair <int, int> > ty_del[N * 4];

vector <int > pshx[N * 4];

vector <pair <int, int> > psh_dely[N * 4];

bool mk[N], mkr[N][2];

vector <pair <int, int> > g;

void Pushx(int v, int tl, int tr)
{
    while (sz(pshx[v]) > 0)
    {
        int val = pshx[v].back();

        pshx[v].pop_back();

        tx[v].insert(val);

        if (tl != tr) {pshx[v + v].pb(val); pshx[v + v + 1].pb(val);}
    }
}

void upd(int v, int tl, int tr, int l, int r, int val)
{
    if (r < tl || tr < l) return;

    if (l <= tl && tr <= r) { pshx[v].pb(val); return;}

    int md = (tl + tr) >> 1;

    upd(v + v, tl, md, l, r, val);

    upd(v + v + 1, md + 1, tr, l, r, val);
}

void Push_dely(int v, int tl, int tr)
{
    while (sz(psh_dely[v]) > 0)
    {
        pair <int, int>  pt = psh_dely[v].back();

        psh_dely[v].pop_back();

        ty_del[v].insert(pt);

        if (tl != tr) {psh_dely[v + v].pb(pt); psh_dely[v + v + 1].pb(pt); }
    }
}

void upd_del(int v, int tl, int tr, int l, int r, pair <int, int> val)
{
    if (tl > tr || l > r || r < tl || tr < l) return;

    if (l <= tl && tr <= r) {psh_dely[v].pb(val); return;}

    int md = (tl + tr) >> 1;

    upd_del(v + v, tl, md, l, r, val);

    upd_del(v + v + 1, md + 1, tr, l, r, val);
}

bool good(int v, int tl, int tr, int pos, int l, int r)
{
    Pushx(v, tl, tr);

    if (tl == tr)
    {
        auto it = tx[v].lower_bound(l);

        return (it == tx[v].end() ? 1 : *it > r);
    }
    else
    {
        int md = (tl + tr) >> 1;

        if (pos <= md) return good(v + v, tl, md, pos, l, r);

        return good(v + v + 1, md + 1, tr, pos, l, r);
    }
}
bool gd(int fr, int sc)
{
    if (x[fr] > x[sc]) swap(fr, sc);

    return good(1, 1, N - 1, y[fr], x[fr], x[sc]);
}
void add_remove(int fr, int sc, int nm)
{
    if (!mk[fr])  alone.insert(fr);

    if (!mk[sc])  alone.insert(sc);
}

void good_del(int v, int tl, int tr, int pos, int l, int r)
{
    Push_dely(v, tl, tr);

    if (tl == tr)
    {
        set <pair <int, int> > :: iterator it;

        it = ty_del[v].lower_bound({l, -1e9});

        while (it != ty_del[v].end() && (*it).F <= r) {add_remove(b[(*it).S], (*it).S, (*it).S); it++;}
    }
    else
    {
        int md = (tl + tr) >> 1;

        if (pos <= md) good_del(v + v, tl, md, pos, l, r);
          else  good_del(v + v + 1, md + 1, tr, pos, l, r);
    }
}

void seacrh(int fr, int sc)
{
    if (x[fr] > x[sc]) swap(fr, sc);

    good_del(1, 1, N, y[fr], x[fr], x[sc]);
}

void add(int fr, int sc)
{
    g.pb({fr, sc});

    if (x[fr] > x[sc]) swap(fr, sc);

    upd(1, 1, N - 1, x[fr], x[sc], y[fr]);

    seacrh(fr, sc);
}

void clr(int x)
{
    mk[x] = 1;

    if (a[x][1] != -1) {if (!mk[a[x][1]])  alone.insert(a[x][1]); a[x][1] = a[a[x][1]][1] = -1;}

    if (a[x][0] != -1) a[x][0] = a[a[x][0]][0] = -1;
}

void adder(int v)
{
    if (mk[v]) return;

    if (a[v][1] != -1) {add(v, a[v][1]); clr(a[v][1]); clr(v); return;}

    if (a[v][0] != -1 && gd(v, a[v][0])) return;

    cout << "NE" << endl;

    exit(0);
}

void fnd()
{
    while (sz(alone) > 0)
    {
        int v = *alone.begin();

        alone.erase(alone.begin());

        adder(v);
    }

    for (int i = 0; i < n; i++)
    {
        if (mk[i]) continue;

        if (!gd(i, a[i][0])) {cout << "NE" << endl; exit(0);}

        g.pb({i, a[i][0]});

        mk[a[i][0]] = 1;
    }
}

void add_del(int fr, int sc)
{
    if (mkr[fr][0]) return;

    mkr[fr][0] = 1;

    mkr[sc][0] = 1;

    if (y[fr] > y[sc]) swap(fr, sc);

    upd_del(1, 1, N, y[fr], y[sc], {x[fr], fr });
}
int main()
{
    ios_base::sync_with_stdio(0); istream::sync_with_stdio(0); cin.tie(0); cout.tie(0);

    cin >> n;

    for (int i = 1; i < N; i++) xr[i] = yr[i] = -1;

    for (int i = 0; i < n; i++) {cin >> x[i] >> y[i]; a[i][0] = a[i][1] = -1;}

    for (int i = 0; i < n; i++)
        {
            int X = x[i], Y = y[i];

            if (xr[X] == -1) xr[X] = i; else {a[i][0] = xr[X]; a[xr[X]][0] = i;}

            if (yr[Y] == -1) yr[Y] = i; else {a[i][1] = yr[Y]; a[yr[Y]][1] = i;}
        }

    for (int i = 0; i < n; i++)
    {
        b[i] = a[i][0];

        if (a[i][0] == a[i][1] && a[i][1] == -1) {cout << "NE" << endl; exit(0);}

        if (!(a[i][0] == -1 || a[i][1] == -1)) add_del(i, a[i][0]);
    }

    for (int i = 0; i < n; i++) if (a[i][0] == -1) adder(i);

    fnd();

    if (sz(g) != n / 2) {cout << "NE" << endl; exit(0);}

    cout << "DA" << endl;

    for (auto it : g) cout << it.F + 1 << " " << it.S + 1 << endl;
}
# Verdict Execution time Memory Grader output
1 Correct 37 ms 57472 KB Output is correct
2 Correct 37 ms 57464 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 37 ms 57472 KB Output is correct
2 Correct 37 ms 57464 KB Output is correct
3 Correct 37 ms 57472 KB Output is correct
4 Correct 37 ms 57472 KB Output is correct
5 Correct 37 ms 57464 KB Output is correct
6 Incorrect 37 ms 57464 KB Output isn't correct
7 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 37 ms 57472 KB Output is correct
2 Correct 37 ms 57464 KB Output is correct
3 Correct 37 ms 57472 KB Output is correct
4 Correct 37 ms 57472 KB Output is correct
5 Correct 37 ms 57464 KB Output is correct
6 Incorrect 37 ms 57464 KB Output isn't correct
7 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 37 ms 57472 KB Output is correct
2 Correct 37 ms 57464 KB Output is correct
3 Correct 37 ms 57472 KB Output is correct
4 Correct 37 ms 57472 KB Output is correct
5 Correct 37 ms 57464 KB Output is correct
6 Incorrect 37 ms 57464 KB Output isn't correct
7 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 37 ms 57472 KB Output is correct
2 Correct 37 ms 57464 KB Output is correct
3 Correct 37 ms 57472 KB Output is correct
4 Correct 37 ms 57472 KB Output is correct
5 Correct 37 ms 57464 KB Output is correct
6 Incorrect 37 ms 57464 KB Output isn't correct
7 Halted 0 ms 0 KB -