Submission #1124406

#TimeUsernameProblemLanguageResultExecution timeMemory
1124406dwuyPlahte (COCI17_plahte)C++17
160 / 160
338 ms62072 KiB
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;

struct BIT{
    int n;
    vector<int> tree;

    BIT(int n = 0) : n(n), tree(n + 5, 0) {}

    void update(int idx, int val){
        for(; idx<=n; idx+=-idx&idx) tree[idx] += val;
    }

    int get(int idx){
        int res = 0;
        for(; idx; idx-=-idx&idx) res += tree[idx];
        return res;
    }

    int get(int l, int r ){
        return get(r) - get(l - 1);
    }
};

const int MX = 240008;
int n, m;
int ans[MX];
struct Rect{ int x, y, u, v; } a[MX];
struct Point{ int x, y, w; } b[MX];
vector<int> G[MX];
vector<int> T[MX];
vector<int> R[MX];
vector<int> ry;

namespace DWUY{

    struct Nium{
        int x, y, l, r, t, id;
        Nium(int x, int l, int r, int t, int id) : x(x), l(l), r(r), t(t), id(id) {}
        Nium(int x, int y, int t, int id) : x(x), y(y), t(t), id(id) {}
        bool operator < (const Nium &o) const{
            return x != o.x ? x < o.x : t < o.t;
        }
    };

    vector<int> p[MX*4];

    void insert(int l, int r, int id, const int &u, const int &v, const int &val){
        if(l > v || r < u) return;
        if(l >= u && r <= v){
            p[id].push_back(val);
            return;
        }
        int mid = (l + r)>>1;
        insert(l, mid, id<<1, u, v, val);
        insert(mid + 1, r, id<<1|1, u, v, val);
    }

    void erase(int l, int r, int id, const int  &u, const int &v){
        if(l > v || r < u) return;
        if(l >= u && r <= v){
            p[id].pop_back();
            return;
        }
        int mid = (l + r)>>1;
        erase(l, mid, id<<1, u, v);
        erase(mid + 1, r, id<<1|1, u, v);
    }

    int get(int l, int r, int id, const int &u, const int &v){
        if(l > v || r < u) return 0;
        if(l >= u && r <= v) return p[id].size()? p[id].back() : 0;
        int res = p[id].size()? p[id].back() : 0;
        int mid = (l + r)>>1;
        int L = get(l, mid, id<<1, u, v);
        int R = get(mid + 1, r, id<<1|1, u, v);
        if(a[L].x > a[res].x) res = L;
        if(a[R].x > a[res].x) res = R;
        return res;
    }

    void build(){
        vector<Nium> vt;
        for(int i=1; i<=n; i++){
            vt.push_back(Nium(a[i].x, a[i].y, a[i].v, 1, i));
            vt.push_back(Nium(a[i].u, a[i].y, a[i].v, 3, i));
        }
        for(int i=1; i<=m; i++){
            vt.push_back(Nium(b[i].x, b[i].y, 2, i));
        }
        sort(vt.begin(), vt.end());
        for(Nium &nium: vt){
            if(nium.t == 1){
                int p =get(1, ry.size(), 1, nium.l, nium.r);
                G[p].push_back(nium.id);
                insert(1, ry.size(), 1, nium.l, nium.r, nium.id);
            }
            if(nium.t == 2){
                int p = get(1, ry.size(), 1, nium.y, nium.y);
                T[p].push_back(nium.id);
            }
            if(nium.t == 3) erase(1, ry.size(), 1, nium.l, nium.r);
        }
    }
}

int peak = 0;
int num[MX];
int rnum[MX];
int clo[MX];

void dfs(int u){
    num[u] = ++peak;
    rnum[num[u]] = u;
    for(int v: G[u]){
        dfs(v);
    }
    clo[u] = peak;
    R[peak].push_back(u);
}

int32_t main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;
    for(int i=1; i<=n; i++){
        int x, y, u, v;
        cin >> x >> y >> u >> v;
        a[i] = {x, y, u, v};
        ry.push_back(y);
        ry.push_back(v);
    }

    for(int i=1; i<=m; i++){
        int x, y, k;
        cin >> x >> y >> k;
        b[i] = {x, y, k};
        ry.push_back(y);
    }

    sort(ry.begin(), ry.end());
    ry.erase(unique(ry.begin(), ry.end()), ry.end());

    for(int i=1; i<=n; i++){
        a[i].y = lower_bound(ry.begin(), ry.end(), a[i].y) - ry.begin() + 1;
        a[i].v = lower_bound(ry.begin(), ry.end(), a[i].v) - ry.begin() + 1;
    }
    for(int i=1; i<=m; i++){
        b[i].y = lower_bound(ry.begin(), ry.end(), b[i].y) - ry.begin() + 1;
    }

    DWUY::build();

    dfs(0);
    BIT bit(peak);
    map<int, int> mp;
    for(int i=1; i<=peak; i++){
        int u = rnum[i];
        for(int c: T[u]){
            int w = b[c].w;
            if(mp[w]) bit.update(mp[w], -1);
            bit.update(i, 1);
            mp[w] = i;
        }
        for(int u: R[i]){
            ans[u] = bit.get(num[u], clo[u]);
        }
    }

    for(int i=1; i<=n; i++) cout << ans[i] << '\n';

    return 0;
}
#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...