답안 #738551

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
738551 2023-05-09T05:21:02 Z GrindMachine Plahte (COCI17_plahte) C++17
128 / 160
2000 ms 110192 KB
// Om Namah Shivaya

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

template<typename T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long int ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define fastio ios_base::sync_with_stdio(false); cin.tie(NULL)
#define pb push_back
#define endl '\n'
#define sz(a) a.size()
#define setbits(x) __builtin_popcountll(x)
#define ff first
#define ss second
#define conts continue
#define ceil2(x, y) ((x + y - 1) / (y))
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define yes cout << "Yes" << endl
#define no cout << "No" << endl

#define rep(i, n) for(int i = 0; i < n; ++i)
#define rep1(i, n) for(int i = 1; i <= n; ++i)
#define rev(i, s, e) for(int i = s; i >= e; --i)
#define trav(i, a) for(auto &i : a)

template<typename T>
void amin(T &a, T b) {
    a = min(a, b);
}

template<typename T>
void amax(T &a, T b) {
    a = max(a, b);
}

#ifdef LOCAL
#include "debug.h"
#else
#define debug(x) 42
#endif

/*



*/

const int MOD = 1e9 + 7;
const int N = 8e4 + 5;
const int inf1 = int(1e9) + 5;
const ll inf2 = ll(1e18) + 5;

template<typename T>
struct segtree {
    // https://codeforces.com/blog/entry/18051

    /*=======================================================*/

    struct data {
        set<pii> st;
    };

    data neutral = {};

    data merge(data &left, data &right) {
        return data();
    }

    void create(int i, T v) {

    }

    void modify(int i, T v) {

    }

    /*=======================================================*/

    int n;
    vector<data> tr;

    segtree() {

    }

    segtree(int siz) {
        init(siz);
    }

    void init(int siz) {
        n = siz;
        tr.assign(2 * n, neutral);
    }

    void build(vector<T> &a, int siz) {
        rep(i, siz) create(i + n, a[i]);
        rev(i, n - 1, 1) tr[i] = merge(tr[i << 1], tr[i << 1 | 1]);
    }

    void pupd(int i, T v) {
        pii p = {v[1], v[2]};

        for (i += n; i; i >>= 1) {
            if (v[0] == 1) {
                tr[i].st.insert(p);
            }
            else {
                tr[i].st.erase(p);
            }
        }
    }

    pii query(int l, int r, int mn) {
        pii best = {inf1, inf1};
        pii key = {mn, -1};

        for (l += n, r += n; l <= r; l >>= 1, r >>= 1) {
            if (l & 1) {
                auto &st = tr[l++].st;
                auto it = st.lower_bound(key);
                if (it != st.end()) {
                    amin(best, *it);
                }
            }

            if (!(r & 1)) {
                auto &st = tr[r--].st;
                auto it = st.lower_bound(key);
                if (it != st.end()) {
                    amin(best, *it);
                }
            }
        }

        return best;
    }
};

vector<int> adj[N];
vector<int> subsiz(N);

void dfs1(int u, int p) {
    subsiz[u] = 1;
    trav(v, adj[u]) {
        if (v == p) conts;
        dfs1(v, u);
        subsiz[u] += subsiz[v];
    }
}

vector<int> ans(N);
set<int> here[N];
set<int> st[N];

void dfs2(int u, int p) {
    int mx = -1, largest = -1;
    trav(v, adj[u]) {
        if (v == p) conts;
        if (subsiz[v] > mx) {
            mx = subsiz[v];
            largest = v;
        }
    }

    if (largest != -1) {
        dfs2(largest, u);
        swap(st[u], st[largest]);
    }

    trav(v, adj[u]) {
        if (v == p or v == largest) conts;
        dfs2(v, u);

        trav(x, st[v]) {
            st[u].insert(x);
        }

        st[v].clear();
    }

    trav(x, here[u]) {
        st[u].insert(x);
    }

    ans[u] = sz(st[u]);
}

void solve(int test_case)
{
    int n, m; cin >> n >> m;
    vector<array<int, 4>> a(n);
    vector<array<int, 3>> b(m);
    rep(i, n) rep(j, 4) cin >> a[i][j];
    rep(i, m) rep(j, 3) cin >> b[i][j];

    vector<pair<ll, int>> process_order;
    rep(i, n) {
        ll area = (ll) (a[i][2] - a[i][0]) * (a[i][3] - a[i][1]);
        process_order.pb({area, i});
    }

    sort(all(process_order));

    vector<pii> points;
    rep(i, n) points.pb({a[i][0], a[i][1]});
    rep(i, m) points.pb({b[i][0], b[i][1]});
    sort(all(points));
    points.resize(unique(all(points)) - points.begin());
    int siz = sz(points);

    segtree<array<int, 3>> st(siz + 5);
    vector<int> par(n, -1);

    for (auto [area, i] : process_order) {
        auto [x1, y1, x2, y2] = a[i];
        pii p = {x1, -1};
        int l = lower_bound(all(points), p) - points.begin();
        p = {x2 + 1, -1};
        int r = upper_bound(all(points), p) - points.begin() - 1;

        while (true) {
            auto [mny, j] = st.query(l, r, y1);
            if (mny > y2) break;

            adj[i].pb(j);
            par[j] = i;

            p = {a[j][0], a[j][1]};
            int ind = lower_bound(all(points), p) - points.begin();
            st.pupd(ind, {2, a[j][1], j});
        }

        p = {x1, y1};
        int ind = lower_bound(all(points), p) - points.begin();
        st.pupd(ind, {1, a[i][1], i});
    }

    st = segtree<array<int, 3>>(siz + 5);
    rep(j, m) {
        auto [x, y, c] = b[j];
        pii p = {x, y};
        int ind = lower_bound(all(points), p) - points.begin();
        st.pupd(ind, {1, y, j});
    }

    for (auto [area, i] : process_order) {
        auto [x1, y1, x2, y2] = a[i];
        pii p = {x1, -1};
        int l = lower_bound(all(points), p) - points.begin();
        p = {x2 + 1, -1};
        int r = upper_bound(all(points), p) - points.begin() - 1;

        while (true) {
            auto [mny, j] = st.query(l, r, y1);
            if (mny > y2) break;

            int c = b[j][2];
            here[i].insert(c);

            p = {b[j][0], b[j][1]};
            int ind = lower_bound(all(points), p) - points.begin();
            st.pupd(ind, {2, b[j][1], j});
        }
    }

    rep(i, n) {
        if (par[i] == -1) {
            dfs1(i, -1);
            dfs2(i, -1);
        }
    }

    rep(i, n) cout << ans[i] << endl;
}

int main()
{
    fastio;

    int t = 1;
    // cin >> t;

    rep1(i, t) {
        solve(i);
    }

    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 505 ms 45216 KB Output is correct
2 Correct 496 ms 44868 KB Output is correct
3 Correct 5 ms 10352 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 461 ms 43668 KB Output is correct
2 Correct 526 ms 42648 KB Output is correct
3 Correct 5 ms 10332 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 883 ms 69136 KB Output is correct
2 Correct 1038 ms 68588 KB Output is correct
3 Correct 6 ms 10324 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1695 ms 106556 KB Output is correct
2 Execution timed out 2071 ms 100312 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1717 ms 104564 KB Output is correct
2 Correct 1807 ms 110192 KB Output is correct
3 Correct 8 ms 10580 KB Output is correct