Submission #1366047

#TimeUsernameProblemLanguageResultExecution timeMemory
1366047khanhphucscratchNew Home (APIO18_new_home)C++20
57 / 100
5117 ms857936 KiB
#include<bits/stdc++.h>
using namespace std;
const int oo = 1e9, big = 2e8, maxn = 6e6; /**/
struct Segtree
{
    priority_queue<pair<int, int>> w[maxn+20];
    int st[maxn+20];
    bool deleted[maxn+20];
    void build(int node, int l, int r)
    {
        st[node] = -oo;
        if(l < r){
            build(node*2, l, (l+r)/2);
            build(node*2+1, (l+r)/2+1, r);
        }
    }
    void add(int node, int l, int r, int tl, int tr, int v, int idx)
    {
        if(l > tr || r < tl) return;
        if(l >= tl && r <= tr){
            w[node].push({v, idx});
            st[node] = w[node].top().first;
        }
        else{
            add(node*2, l, (l+r)/2, tl, tr, v, idx);
            add(node*2+1, (l+r)/2+1, r, tl, tr, v, idx);
        }
    }
    void del(int node, int l, int r, int tl, int tr, int idx)
    {
        if(l > tr || r < tl) return;
        deleted[idx] = 1;
        if(l >= tl && r <= tr){
            while(w[node].size() > 0 && deleted[w[node].top().second] == 1) w[node].pop();
            if(w[node].size() > 0) st[node] = w[node].top().first;
            else st[node] = -oo;
        }
        else{
            del(node*2, l, (l+r)/2, tl, tr, idx);
            del(node*2+1, (l+r)/2+1, r, tl, tr, idx);
        }
    }
    int query(int node, int l, int r, int p)
    {
        if(l == r) return st[node];
        else{
            int mid = (l+r)/2;
            if(p <= mid) return max(st[node], query(node*2, l, mid, p));
            else return max(st[node], query(node*2+1, mid+1, r, p));
        }
    }
};
struct Stores
{
    int x, t, l, r;
};
struct Rectangle
{
    int l1, r1, l2, r2, val, type;
    Rectangle(int l1, int r1, int l2, int r2, int val, int type): l1(l1), r1(r1), l2(l2), r2(r2), val(val), type(type){}
};
multiset<pair<int, int>> cur_store[300005];
int aft_time[1000005];

vector<Rectangle> rec;
void add(int l, int r, int lt, int rt)
{
    if(lt > rt) return; /**/
    int mid = (l+r)/2;
    //Remove some trash rectangle
    if(mid >= 0) rec.emplace_back(max(l, 0), mid, lt, rt, -l, 1);
    if(mid < r && mid+1 <= big) rec.emplace_back(mid+1, min(r, big), lt, rt, r, 2);
}
vector<pair<int, int>> wq[maxn];
vector<int> rec_add[maxn], rec_del[maxn];
int ans[maxn];
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n, m, q; cin>>n>>m>>q;
    vector<Stores> a(n);
    for(int i = 0; i < n; i++) cin>>a[i].x>>a[i].t>>a[i].l>>a[i].r;
    vector<pair<int, int>> store_order;
    for(int i = 0; i < n; i++){
        store_order.push_back({a[i].l, i+1});
        store_order.push_back({a[i].r+1, -i-1});
    }
    sort(store_order.begin(), store_order.end());
    //Now calculate the rectanges
    int ssz = n+1;
    for(int i = 1; i <= m; i++){
        cur_store[i].insert({-oo, ++ssz});
        cur_store[i].insert({oo, ++ssz});
    }
    for(pair<int, int> i : store_order){
        int idx = i.second, t = i.first;
        pair<int, int> adp = make_pair(a[abs(idx)-1].x, abs(idx)-1);
        if(idx > 0){
            idx--;
            multiset<pair<int, int>>::iterator it = cur_store[a[idx].t].lower_bound(adp);
            it--; int l = (*it).second, lx = (*it).first; it++; int r = (*it).second, rx = (*it).first;
            //cerr<<"AAAAAAAAAAA"<<endl;
            add(lx, rx, aft_time[l], t-1);
            aft_time[l] = aft_time[idx] = t; cur_store[a[idx].t].insert(adp);
        }
        else{
            idx = -idx; idx--;
            multiset<pair<int, int>>::iterator it = cur_store[a[idx].t].lower_bound(adp);
            it--; int l = (*it).second, lx = (*it).first; it++; it++; int r = (*it).second, rx = (*it).first; it--;
            //cerr<<"BBBBBBBBBBBBBB"<<endl;
            add(lx, a[idx].x, aft_time[l], t-1);
            add(a[idx].x, rx, aft_time[idx], t-1);
            //cerr<<"A"<<idx<<" "<<l<<endl;
            aft_time[l] = t; cur_store[a[idx].t].erase(it);
        }
    }
    //Add the remaining rectangles
    for(int i = 1; i <= m; i++){
        int l = -oo, r = oo, t = aft_time[(*cur_store[i].begin()).second];
        add(l, r, t, oo);
    }
    //for(int i = 0; i < rec.size(); i++) cerr<<"A"<<rec[i].l1<<" "<<rec[i].r1<<" "<<rec[i].l2<<" "<<rec[i].r2<<" "<<rec[i].val<<" "<<rec[i].type<<endl;
    //Read the queries
    vector<pair<int, int>> queries(q);
    for(int i = 0; i < q; i++) cin>>queries[i].first>>queries[i].second;
    //Compress everything
    vector<int> vec1, vec2;
    for(int i = 0; i < rec.size(); i++){
        vec1.push_back(rec[i].l1); vec1.push_back(rec[i].r1);
        vec2.push_back(rec[i].l2); vec2.push_back(rec[i].r2);
    }
    for(int i = 0; i < q; i++){
        vec1.push_back(queries[i].first);
        vec2.push_back(queries[i].second);
    }
    sort(vec1.begin(), vec1.end()); vec1.erase(unique(vec1.begin(), vec1.end()), vec1.end());
    sort(vec2.begin(), vec2.end()); vec2.erase(unique(vec2.begin(), vec2.end()), vec2.end());
    for(int i = 0; i < rec.size(); i++){
        rec[i].l1 = upper_bound(vec1.begin(), vec1.end(), rec[i].l1) - vec1.begin();
        rec[i].r1 = upper_bound(vec1.begin(), vec1.end(), rec[i].r1) - vec1.begin();
        rec[i].l2 = upper_bound(vec2.begin(), vec2.end(), rec[i].l2) - vec2.begin();
        rec[i].r2 = upper_bound(vec2.begin(), vec2.end(), rec[i].r2) - vec2.begin();
    }
    for(int i = 0; i < q; i++){
        queries[i].first = upper_bound(vec1.begin(), vec1.end(), queries[i].first) - vec1.begin();
        queries[i].second = upper_bound(vec2.begin(), vec2.end(), queries[i].second) - vec2.begin();
    }
    //for(int i = 0; i < rec[i].size(); i++) cerr<<"A"<<rec[i].l1<<" "<<rec[i].r1<<" "<<rec[i].l2<<" "<<rec[i].r2<<" "<<rec[i].val<<" "<<rec[i].type<<endl;
    //Now actually solve the problem
    n = vec1.size(); m = vec2.size();
    for(int i = 0; i < rec.size(); i++){
        rec_add[rec[i].l2].push_back(i);
        rec_del[rec[i].r2].push_back(i);
    }
    for(int i = 0; i < q; i++){
        wq[queries[i].second].push_back({queries[i].first, i});
    }
    //Sweep line
    Segtree st1, st2;
    st1.build(1, 1, n); st2.build(1, 1, n);
    for(int i = 1; i <= m; i++){
        for(int j : rec_add[i]){
            if(rec[j].type == 1) st1.add(1, 1, n, rec[j].l1, rec[j].r1, rec[j].val, j);
            else st2.add(1, 1, n, rec[j].l1, rec[j].r1, rec[j].val, j);
        }
        //Now solve the queries
        for(pair<int, int> j : wq[i]){
            int x = j.first, idx = j.second;
            ans[idx] = max(vec1[x-1]+st1.query(1, 1, n, x), -vec1[x-1]+st2.query(1, 1, n, x));
            //cerr<<"B"<<st1.query(1, 1, n, x)<<" "<<st2.query(1, 1, n, x)<<" "<<vec1[x-1]<<endl;
        }
        for(int j : rec_del[i]){
            if(rec[j].type == 1) st1.del(1, 1, n, rec[j].l1, rec[j].r1, j);
            else st2.del(1, 1, n, rec[j].l1, rec[j].r1, j);
        }
    }
    //Answer
    for(int i = 0; i < q; i++){
        if(ans[i] > big) cout<<-1<<'\n';
        else cout<<ans[i]<<'\n';
    }
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...