제출 #1154682

#제출 시각아이디문제언어결과실행 시간메모리
1154682Zero_OP새 집 (APIO18_new_home)C++20
0 / 100
5101 ms397068 KiB
#include <bits/stdc++.h>

using namespace std;

#define FOR(i, l, r) for(int i = (l); i < (r); ++i)
#define ROF(i, l, r) for(int i = (r) - 1; i >= (l); --i)
#define rep(i, l, r) for(int i = (l); i < (r); ++i)

#define mp make_pair
#define mt make_tuple
#define ff first
#define ss second

#define all(v) begin(v), end(v)
#define rall(v) rbegin(v), rend(v)
#define compact(v) v.erase(unique(all(v)), end(v))
#define sz(v) (int)v.size()
#define sum_of(v) accumluate(all(v), 0ll)
#define max_of(v) *max_element(all(v))
#define min_of(v) *min_element(all(v))
#define pb push_back
#define eb emplace_back

#define dbg(x) "[" #x " = " << (x) << "]"
#define inputFile(task) freopen(task, "r", stdin);
#define outputFile(task) freopen(task, "w", stdout);

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

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

using ll = long long;
using db = double;
using ull = unsigned long long;
using ldb = long double;

using pi = pair<int, int>;
using pl = pair<ll, ll>;
using pd = pair<db, db>;

using vi = vector<int>;
using vl = vector<ll>;
using vd = vector<db>;
using vb = vector<bool>;

using vpi = vector<pi>;
using vpl = vector<pl>;

void setIO(){
      ios_base::sync_with_stdio(0); cin.tie(0);
#ifdef LOCAL
      inputFile("task.inp");
//      outputFile("task.out");
#endif // LOCAL
}

const int MAX = 3e5 + 5;
const int BOUND = 2e8;
const int inf_bound = 1e9 + 1;
const int inf = 1e9 + 9;

int N, K, Q, x[MAX], t[MAX], a[MAX], b[MAX], l[MAX], y[MAX];
vector<tuple<int, int, int>> lines; //[l, r, v]

vi queries_blocks[MAX << 3];
vector<tuple<int, int, int>> events_blocks[MAX << 3];
int result[MAX];

namespace SegmentTree{
      int n, mn[MAX << 3], mx[MAX << 3];
      void init(int _n){
            n = _n;
            for(int i = 1; i < 2 * n; ++i){
                  mn[i] = +inf;
                  mx[i] = -inf;
            }
      }

      void update(int l, int r, int v){
            l += n; r += n+1;
            for(; l < r; l >>= 1, r >>= 1){
                  if(l & 1){
                        minimize(mn[l], v);
                        maximize(mx[l], v);
                        ++l;
                  }

                  if(r & 1){
                        --r;
                        minimize(mn[r], v);
                        maximize(mx[r], v);
                  }
            }
      }

      pi get_min_max(int i){
            i += n;
            int a = inf, b = -inf;
            for(; i > 0; i >>= 1){
                  minimize(a, mn[i]);
                  maximize(b, mx[i]);
            }
            return mp(a, b);
      }
}

void add_query(int id, int l, int r, int pos, int idx){
      queries_blocks[id].pb(idx);
      if(l + 1 == r) return;
      else{
            int mid = l + r >> 1;
            if(pos < mid) add_query(id << 1, l, mid, pos, idx);
            else add_query(id << 1 | 1, mid, r, pos, idx);
      }
}

void add_event(int id, int l, int r, int u, int v, pi range){
      if(u <= l && r <= v) {
            if(range.ff == 0 && range.ss == BOUND){
                  events_blocks[id].pb(mt(range.ff, range.ss, inf_bound));
                  return;
            }

            if(range.ff == 0){
                  events_blocks[id].pb(mt(0, range.ss, range.ss));
                  return;
            }

            if(range.ss == BOUND){
                  events_blocks[id].pb(mt(range.ff, BOUND, range.ff));
                  return;
            }

            int mid = (range.ff + range.ss) / 2;
            if(range.ff < mid) events_blocks[id].pb(mt(range.ff+1, mid, (range.ff == 0 ? range.ss : range.ff)));
            if(mid < range.ss) events_blocks[id].pb(mt(mid+1, range.ss, (range.ss == BOUND ? range.ff : range.ss)));
      }
      else{
            int mid = l + r >> 1;
            if(u < mid) add_event(id << 1, l, mid, u, v, range);
            if(mid < v) add_event(id << 1 | 1, mid, r, u, v, range);
      }
}

void dfs(int id, int l, int r){
      vi ps;
      for(auto [l, r, v] : events_blocks[id]) ps.pb(l), ps.pb(r);
      for(auto it : queries_blocks[id]) ps.pb(::l[it]);
      sort(all(ps)); compact(ps);
      int n = sz(ps);
      SegmentTree::init(n);

//      cout << dbg(id) << '\n';
//      for(auto [l, r, v] : events_blocks[id]) cout << dbg(l) << dbg(r) << dbg(v) << '\n';
//      for(auto idx : queries_blocks[id]) {
//            cout << dbg(idx) << '\n';
//      }

      for(auto [l, r, v] : events_blocks[id]){
            l = lower_bound(all(ps), l) - ps.begin();
            r = lower_bound(all(ps), r) - ps.begin();
            SegmentTree::update(l, r, v);
      }

      for(auto idx : queries_blocks[id]){
            pi cur = SegmentTree::get_min_max(lower_bound(all(ps), ::l[idx]) - ps.begin());
            if(cur.first == inf || cur.second == -inf) continue;
//            cout << cur.ff << ' ' << cur.ss << '\n';
//            cout << ::l[idx] << '\n';
//            cout << max(abs(::l[idx] - cur.ff), abs(::l[idx] - cur.ss)) << '\n';
            maximize(result[idx], max(abs(cur.ff - ::l[idx]), abs(cur.ss - ::l[idx])));
      }

      if(l + 1 < r){
            int mid = l + r >> 1;
            dfs(id << 1, l, mid);
            dfs(id << 1 | 1, mid, r);
      }
}

int main(){
      setIO();

      cin >> N >> K >> Q;
      FOR(i, 0, N) cin >> x[i] >> t[i] >> a[i] >> b[i], --t[i];
      FOR(i, 0, Q) cin >> l[i] >> y[i];

      vi tm(y, y + Q);
      sort(all(tm)); compact(tm);

      int ts = sz(tm);
      FOR(i, 0, Q){
            y[i] = lower_bound(all(tm), y[i]) - tm.begin();
            add_query(1, 0, ts, y[i], i);
//            cout << y[i] << ' ' << i << '\n';
      }

      FOR(i, 0, N){
            a[i] = lower_bound(all(tm), a[i]) - tm.begin();
            b[i] = lower_bound(all(tm), b[i]) - tm.begin();
//            cout << a[i] << ' ' << b[i] << '\n';
            if(a[i] == b[i]) continue;
      }

      vi idx(N); iota(all(idx), 0);
      sort(all(idx), [&](int a, int b){ return t[a] < t[b]; });
      int ptr = 0;

      FOR(i, 0, K){
//            cout << dbg(i) << '\n';
            vector<tuple<int, int, int>> events;
            while(ptr < N && t[idx[ptr]] == i){
                  int id = idx[ptr];
                  if(a[id] < b[id]){
                        events.pb(mt(a[id], +1, id));
                        events.pb(mt(b[id], -1, id));
                  }
                  ++ptr;
            }

            sort(all(events));
            multiset<int> online;
            online.insert(0);
            online.insert(BOUND);
            map<pi, int> mpp;
            mpp[{0, BOUND}] = 0;
            for(auto [t, type, id] : events){
                  int x = ::x[id];
                  if(type == -1){
                        online.erase(online.lower_bound(x));
                        if(online.find(x) == online.end()){
                              auto ub = online.upper_bound(x);
                              auto lb = prev(ub);
                              int L = *lb, R = *ub;
                              assert(L <= R);
//                              cout << "[" << mpp[mp(L, x)] << ", " << t << ") : " << L << ' ' << x << '\n';
//                              cout << "[" << mpp[mp(x, R)] << ", " << t << ") : " << x << ' ' << R << '\n';
                              add_event(1, 0, ts, mpp[mp(L, x)], t, mp(L, x)); mpp.erase(mpp.find({L, x})); //(L, x]
                              add_event(1, 0, ts, mpp[mp(x, R)], t, mp(x, R)); mpp.erase(mpp.find({x, R})); //(x, R]
                              mpp[mp(L, R)] = t;
                        }
                  } else{
                        if(online.find(x) == online.end()){
                              auto ub = online.upper_bound(x); assert(ub != online.end() && ub != online.begin());
                              auto lb = prev(ub);
                              int L = *lb, R = *ub, pre = mpp[mp(L, R)];
                              assert(L <= R);
//                              cout << "[" << mpp[mp(L, R)] << ", " << t << ") : " << L << ' ' << R << '\n';
                              mpp.erase(mpp.find(mp(L, R)));
                              add_event(1, 0, ts, pre, t, mp(L, R)); //(L, R]
                              mpp[mp(L, x)] = t;
                              mpp[mp(x, R)] = t;
                        }
                        online.insert(x);
                  }
            }

            int lst = mpp[{0, BOUND}];
//            cout << lst << '\n';
            if(lst < ts) {
//                  cout << "[" << lst << ", " << ts << ") : " << 0 << ' ' << BOUND << '\n';
                  add_event(1, 0, ts, lst, ts, mp(0, BOUND));
            }
      }

      dfs(1, 0, ts);

      FOR(i, 0, Q){
            if(result[i] > (int)1e8) result[i] = -1;
            cout << result[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...
#Verdict Execution timeMemoryGrader output
Fetching results...