Submission #1260739

#TimeUsernameProblemLanguageResultExecution timeMemory
1260739icebearNew Home (APIO18_new_home)C++20
0 / 100
222 ms96148 KiB
// ~~ icebear ~~
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> ii;
typedef pair<int, ii> iii;

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

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

#define FOR(i,a,b) for(int i=(a); i<=(b); ++i)
#define FORR(i,a,b) for(int i=(a); i>=(b); --i)
#define REP(i, n) for(int i=0; i<(n); ++i)
#define RED(i, n) for(int i=(n)-1; i>=0; --i)
#define MASK(i) (1LL << (i))
#define BIT(S, i) (((S) >> (i)) & 1)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define all(x) x.begin(), x.end()
#define task "icebear"

const int MOD = 1e9 + 7;
const int inf = 1e9 + 27092008;
const ll INF = 1e18 + 27092008;
const int N = 3e5 + 5;
int numShop, numQuery, numType;
array<int, 4> shop[N];
vector<int> com_pos, com_year;
struct Event {
    int year, pos, type, id;
    Event(int _year = 0, int _pos = 0, int _type = 0, int _id = 0):
        year(_year), pos(_pos), type(_type), id(_id) {}
    bool operator < (const Event &other) const {
        if (year == other.year) return id < other.id;
        return year < other.year;
    }
};
vector<Event> events;

struct SegmentTree {
    multiset<int> node[N << 2];
    vector<int> com_pos;
    int sizeTree;

    void init(vector<int> &com) {
        sizeTree = (int)com.size();
        com_pos = com;
    }

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

    void del(int id, int l, int r, int u, int v, int val) {
        if (l > v || r < u) return;
        if (u <= l && r <= v) {
            if (node[id].find(val) == node[id].end()) {
                cerr << "WANT TO DEL : " << com_pos[u - 1] << ' ' << com_pos[v - 1] << ' ' << val << '\n';
                assert(false);
            }
            node[id].erase(node[id].find(val));
            return;
        }
        int mid = (l + r) >> 1;
        del(id << 1, l, mid, u, v, val);
        del(id << 1 | 1, mid + 1, r, u, v, val);
    }

    void add(int u, int v, int val) {
        u = lower_bound(all(com_pos), u) - com_pos.begin() + 1;
        v = upper_bound(all(com_pos), v) - com_pos.begin();
        if (u > v) return;
        add(1, 1, sizeTree, u, v, val);
    }

    void del(int u, int v, int val) {
        u = lower_bound(all(com_pos), u) - com_pos.begin() + 1;
        v = upper_bound(all(com_pos), v) - com_pos.begin();
        if (u > v) return;
        del(1, 1, sizeTree, u, v, val);
    }

    int getAns(int pos) {
        int ans = 0;
        int id = 1, l = 1, r = sizeTree;
        int com = upper_bound(all(com_pos), pos) - com_pos.begin();
        while(l < r) {
            if (!node[id].empty()) {
                maximize(ans, abs(pos - *node[id].begin()));
                maximize(ans, abs(pos - *node[id].rbegin()));
            }

            int mid = (l + r) >> 1;
            if (com > mid) id = (id << 1 | 1), l = mid + 1;
            else id = (id << 1), r = mid;
        }
        return ans;
    }
} IT;

int ans[N], cur_cnt;
multiset<int> pos_shop[N];

void add_shop(int pos, int type) {
    if (pos_shop[type].find(pos) != pos_shop[type].end()) {
        pos_shop[type].insert(pos);
        return;
    }
    if (pos_shop[type].empty()) cur_cnt++;
    auto it = pos_shop[type].lower_bound(pos);
    int l = -1, r = -1;

    if (it != pos_shop[type].end()) r = *it;
    if (it != pos_shop[type].begin()) l = *(--it);

    if (l != -1 || r != -1) {
//        cerr << "DELETE AT TYPE " << type << " : " << l << ' ' << pos << ' ' << r << '\n';
        if (l == -1) IT.del(1, r, r);
        else if (r == -1) IT.del(l, inf, l);
        else {
            int mid = (l + r) >> 1;
            IT.del(l, mid, l);
            IT.del(mid + 1, r, r);
        }
    }

    if (l == -1) IT.add(1, pos, pos);
    else {
        int mid = (l + pos) >> 1;
        IT.add(l, mid, l);
        IT.add(mid + 1, pos, pos);
    }

    if (r == -1) IT.add(pos, inf, pos);
    else {
        int mid = (pos + r) >> 1;
        IT.add(pos, mid, pos);
        IT.add(mid + 1, r, r);
    }

    pos_shop[type].insert(pos);
}

void del_shop(int pos, int type) {
    pos_shop[type].erase(pos_shop[type].find(pos));
    if (pos_shop[type].find(pos) != pos_shop[type].end()) return;
    if (pos_shop[type].empty()) cur_cnt--;
    auto it = pos_shop[type].upper_bound(pos);
    int l = -1, r = -1;

    if (it != pos_shop[type].end()) r = *it;
    if (it != pos_shop[type].begin()) l = *(--it);

    if (l == -1) IT.del(1, pos, pos);
    else {
        int mid = (l + pos) >> 1;
        IT.del(l, mid, l);
        IT.del(mid + 1, pos, pos);
    }

    if (r == -1) IT.del(pos, inf, pos);
    else {
        int mid = (pos + r) >> 1;
        IT.del(pos, mid, pos);
        IT.del(mid + 1, r, r);
    }

    if (l != -1 || r != -1) {
        if (l == -1) IT.add(1, r, r);
        else if (r == -1) IT.add(l, inf, l);
        else {
            int mid = (l + r) >> 1;
            IT.add(l, mid, l);
            IT.add(mid + 1, r, r);
        }
    }
}

void query(int pos, int id) {
    if (cur_cnt < numType) ans[id] = -1;
    else ans[id] = IT.getAns(pos);
}

void init(void) {
    cin >> numShop >> numType >> numQuery;
    FOR(i, 1, numShop) {
        REP(j, 4) cin >> shop[i][j];
        com_pos.pb(shop[i][0]);
        events.emplace_back(shop[i][2], shop[i][0], shop[i][1], -1);
        events.emplace_back(shop[i][3], shop[i][0], shop[i][1], inf);
    }
    FOR(i, 1, numQuery) {
        int pos, year;
        cin >> pos >> year;
        com_pos.pb(pos);
        events.emplace_back(year, pos, -1, i);
    }
}

void process(void) {
    com_pos.pb(1); com_pos.pb(inf);
    sort(all(com_pos));
    com_pos.resize(unique(all(com_pos)) - com_pos.begin());
    IT.init(com_pos);

    sort(all(events));
    for(auto &e : events) {
        if (e.id < 0) add_shop(e.pos, e.type);
        else if (e.id == inf) del_shop(e.pos, e.type);
        else query(e.pos, e.id);
    }

    FOR(i, 1, numQuery) cout << ans[i] << '\n';
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    if (fopen(task".inp", "r")) {
        freopen(task".inp", "r", stdin);
        freopen(task".out", "w", stdout);
    }
    int tc = 1;
//    cin >> tc;
    while(tc--) {
        init();
        process();
    }
    return 0;
}

Compilation message (stderr)

new_home.cpp: In function 'int main()':
new_home.cpp:239:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  239 |         freopen(task".inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
new_home.cpp:240:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  240 |         freopen(task".out", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...