Submission #1345196

#TimeUsernameProblemLanguageResultExecution timeMemory
1345196shirokitoPlahte (COCI17_plahte)C++20
160 / 160
330 ms100392 KiB
#include <bits/stdc++.h>
using namespace std;

#define UP1(i, n) for (int i = 0; i < (n); i++)
#define UP2(i, a, b) for (int i = (a); i <= (b); i++)
#define UP3(i, a, b, c) for (int i = (a); i <= (b); i += (c))
#define DN1(i, n) for (int i = (n) - 1; i >= 0; i--)
#define DN2(i, a, b) for (int i = (a); i >= (b); i--)
#define DN3(i, a, b, c) for (int i = (a); i >= (b); i -= (c))
#define FOR_IMPL(_1, _2, _3, _4, NAME, ...) NAME
#define FOR_UP(...) FOR_IMPL(__VA_ARGS__, UP3, UP2, UP1) (__VA_ARGS__)
#define FOR_DN(...) FOR_IMPL(__VA_ARGS__, DN3, DN2, DN1) (__VA_ARGS__)

#define POPCOUNT(n) __builtin_popcountll(n)
#define CLZ(n) __builtin_clzll(n)
#define CTZ(n) __builtin_ctzll(n)
#define LOG(n) __lg(n)
#define BIT(n, i) (((n) >> (i)) & 1LL)
#define FLIP(n, i) ((n) ^ (1LL << (i)))
#define ON(n, i) ((n) | (1LL << (i)))
#define OFF(n, i) ((n) & ~(1LL << (i)))

#define all(x) (x).begin(), (x).end()
#define len(x) (int)x.size()

#define fi first
#define se second

using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<long long, long long>;

#if __cplusplus <= 201402L
template <typename T> T gcd(T a, T b) { 
    return __gcd(a, b); 
}
template <typename T> T lcm(T a, T b) {
    return a / gcd(a, b) * b;
}
#endif

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
long long rand(long long l, long long r) {
    return uniform_int_distribution<long long>(l, r)(rng);  
}  

template <class T> void remove_duplicate(vector<T> &v) {
    sort(v.begin(), v.end()); 
    v.resize(unique(v.begin(), v.end()) - v.begin());
} 

template <class T> bool maximize(T &x, const T &y) {
    if (x < y) {
        x = y;
        return true;
    }
    return false;
}
template <class T> bool minimize(T &x, const T &y) {
    if (x > y) {
        x = y;
        return true;
    }
    return false;
}  

const int N = 1e6 + 24;

struct Rectangle {
    int a, b, x, y; ll size;
}; 

struct Shot {
    int x, y, color;
};

int n, m, max_X, max_Y, ans[N]; Rectangle sheet[N];
Shot shot[N];
set<int> inside[N];
map<pii, int> ID;
vector<int> value_X, value_Y;
vector<int> query[N], event[N]; 

void compress() {
    FOR_UP (i, 1, n) {
        value_X.push_back(sheet[i].a);
        value_X.push_back(sheet[i].x);
        value_Y.push_back(sheet[i].b);
        value_Y.push_back(sheet[i].y);
    }

    FOR_UP (i, 1, m) {
        value_X.push_back(shot[i].x);
        value_Y.push_back(shot[i].y);
    }

    remove_duplicate(value_X);
    remove_duplicate(value_Y);

    max_X = len(value_X) - 1;
    max_Y = len(value_Y) - 1;

    auto compress_X = [&](int &value) -> void {
        value = lower_bound(all(value_X), value) - value_X.begin();
    };
    auto compress_Y = [&](int &value) -> void {
        value = lower_bound(all(value_Y), value) - value_Y.begin();
    };

    FOR_UP (i, 1, n) {
        compress_X(sheet[i].a);
        compress_X(sheet[i].x);
        compress_Y(sheet[i].b);
        compress_Y(sheet[i].y);
    }

    FOR_UP (i, 1, m) {
        compress_X(shot[i].x);
        compress_Y(shot[i].y);
    }
}

void sweepline() {
    vector<pii> point;

    FOR_UP (i, 1, n) {
        point.push_back({2 * sheet[i].x, 2 * sheet[i].y + 1});
    }

    FOR_UP (i, 1, m) {
        point.push_back({2 * shot[i].x, 2 * shot[i].y});
    }

    FOR_UP (i, 1, n) {
        event[2 * sheet[i].b].push_back(i);
        event[2 * sheet[i].y + 1].push_back(-i);
    }

    for (auto [x, y]: point) {
        query[y].push_back(x);
    }

    multiset<pii> cut;
    cut.insert({-1, 0});

    auto getColor = [&](int i) -> int {
        auto it = cut.upper_bound({i, 1e9}); it--;
        int color = (*it).se;
        return color;
    };

    FOR_UP (y, 0, 2 * max_Y + 1) {
        for (int i: event[y]) if (i < 0) {
            i = -i;
            cut.erase(cut.find({2 * sheet[i].a, i}));
            auto it = cut.lower_bound({2 * sheet[i].x + 1, -1});
            cut.erase(it);
        }
        for (int i: event[y]) if (i > 0) {
            int color = getColor(2 * sheet[i].a);
            cut.insert({2 * sheet[i].a, i});
            cut.insert({2 * sheet[i].x + 1, color});
        }

        for (int x: query[y]) {
            int color = getColor(x);
            ID[pii(x, y)] = color;
        }
    }
}

void find_answer() {
    FOR_UP (i, 1, m) {
        int id = ID[pii(2 * shot[i].x, 2 * shot[i].y)];
        if (id) inside[id].insert(shot[i].color);
    }

    vector<int> ids; FOR_UP (i, 1, n) {
        ids.push_back(i);
    }

    sort(all(ids), [&] (int i, int j) {
        return sheet[i].size < sheet[j].size;
    });

    for (int i: ids) {
        ans[i] = len(inside[i]);

        int j = ID[pii(2 * sheet[i].x, 2 * sheet[i].y + 1)];

        if (!j) continue;

        if (len(inside[j]) < len(inside[i])) {
            swap(inside[j], inside[i]);
        }

        for (int color: inside[i]) {
            inside[j].insert(color);
        }
    }
}

int main() {
    cin.tie(0) -> sync_with_stdio(0);

    cin >> n >> m; 

    FOR_UP (i, 1, n) {
        cin >> sheet[i].a >> sheet[i].b >> sheet[i].x >> sheet[i].y;
        sheet[i].size = 1LL * (sheet[i].x - sheet[i].a + 1) * (sheet[i].y - sheet[i].b + 1);
    }

    FOR_UP (i, 1, m) {
        cin >> shot[i].x >> shot[i].y >> shot[i].color;
    }

    compress();
    sweepline();
    find_answer();

    FOR_UP (i, 1, n) {
        cout << ans[i] << '\n';
    }
}
#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...