Submission #394023

#TimeUsernameProblemLanguageResultExecution timeMemory
39402379brueNew Home (APIO18_new_home)C++14
0 / 100
5122 ms608072 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int*, int> INFO; struct Mart{ int x, y, t; bool on; /// location, type, time Mart(int x, int y, int t, bool on): x(x), y(y), t(t), on(on){} bool operator<(const Mart &r)const{ return t<r.t; } }; struct Query{ int x, t, idx; Query(){} Query(int x, int t, int idx): x(x), t(t), idx(idx){} bool operator<(const Query &r)const{ return t<r.t; } }; struct Segment{ int a, b, l, r, s, e; Segment(){} Segment(int a, int b, int l, int r, int s, int e): a(a), b(b), l(l), r(r), s(s), e(e){} }; vector<Segment> segment; struct maxSegmentTree{ vector<stack<INFO> > vec; int tree[6000002], lazy[6000002]; void init(int i, int l, int r){ tree[i] = lazy[i] = -1e9; if(l==r) return; int m = (l+r)>>1; init(i*2, l, m), init(i*2+1, m+1, r); } inline void save(){ vec.push_back(stack<INFO> ()); } void undo(){ while(!vec.back().empty()){ INFO tmp = vec.back().top(); *(tmp.first) = tmp.second; vec.back().pop(); } vec.pop_back(); } #define saveinfo(A) vec.back().push(INFO {&A, A}) void propagate(int i, int l, int r){ if(tree[i] < lazy[i]){ saveinfo(tree[i]); tree[i] = max(tree[i], lazy[i]); } if(l!=r){ if(lazy[i*2] < lazy[i]) saveinfo(lazy[i*2]), lazy[i*2] = lazy[i]; if(lazy[i*2+1] < lazy[i]) saveinfo(lazy[i*2+1]), lazy[i*2+1] = lazy[i]; } } void rangeMax(int i, int l, int r, int s, int e, int val){ propagate(i, l, r); if(r<s || e<l) return; if(s<=l && r<=e){ if(lazy[i] >= val) return; saveinfo(lazy[i]); lazy[i] = val; propagate(i, l, r); return; } int m = (l+r)>>1; rangeMax(i*2, l, m, s, e, val); rangeMax(i*2+1, m+1, r, s, e, val); tree[i] = max(tree[i*2], tree[i*2+1]); } int getVal(int i, int l, int r, int idx){ propagate(i, l, r); if(l==r) return tree[i]; int m = (l+r)>>1; if(idx <= m) return getVal(i*2, l, m, idx); return getVal(i*2+1, m+1, r, idx); } } treeA, treeB; int n, q, k; void input(); void createQueries(); void renumber(); void ODCinit(); void ODC(int, int, vector<Segment>&); void output(); int main(){ input(); createQueries(); renumber(); ODCinit(); ODC(1, 100000000, segment); output(); } vector<Mart> vec; vector<Query> qvec; int ans[300002]; void input(){ scanf("%d %d %d", &n, &k, &q); for(int i=1; i<=n; i++){ int x, t, a, b; scanf("%d %d %d %d", &x, &t, &a, &b); vec.push_back(Mart(x, t, a, 1)); vec.push_back(Mart(x, t, b+1, 0)); } sort(vec.begin(), vec.end()); for(int i=1; i<=q; i++){ int l, y; scanf("%d %d", &l, &y); qvec.push_back(Query(l, y, i)); } sort(qvec.begin(), qvec.end()); } multiset<int> mst[300002]; multimap<pair<int, int>, int> mtm; inline void addSegment(int l, int r, int t){ mtm.insert(make_pair(make_pair(l, r), t)); } void delSegment(int l, int r, int e){ auto it = mtm.find(make_pair(l, r)); int s = it->second; mtm.erase(it); if(s>=e) return; int mid = (l+r)/2; segment.push_back(Segment(1, -l, l, mid, s, e-1)); segment.push_back(Segment(-1, r, mid+1, r, s, e-1)); } void createQueries(){ int pnt = 0; qvec.push_back(Query(0, 100000001, 0)); for(int i=1; i<=k; i++){ mst[i].insert(-300000000), mst[i].insert(400000000); addSegment(-300000000, 400000000, 1); } for(int i=0; i<q+1; i++){ while(pnt < 2*n && vec[pnt].t <= qvec[i].t){ Mart tmp = vec[pnt++]; if(tmp.on){ auto it = mst[tmp.y].lower_bound(tmp.x); int l = (it == mst[tmp.y].begin() ? -1 : *prev(it)); int r = (it == mst[tmp.y].end() ? -1 : *it); mst[tmp.y].insert(tmp.x); if(l!=-1 && r!=-1) delSegment(l, r, tmp.t); if(l!=-1) addSegment(l, tmp.x, tmp.t); if(r!=-1) addSegment(tmp.x, r, tmp.t); } else{ mst[tmp.y].erase(mst[tmp.y].find(tmp.x)); auto it = mst[tmp.y].lower_bound(tmp.x); int l = (it == mst[tmp.y].begin() ? -1 : *prev(it)); int r = (it == mst[tmp.y].end() ? -1 : *it); if(l!=-1 && r!=-1) addSegment(l, r, tmp.t); if(l!=-1) delSegment(l, tmp.x, tmp.t); if(r!=-1) delSegment(tmp.x, r, tmp.t); } } } for(int i=1; i<=k; i++){ delSegment(-300000000, 400000000, 100000000); } assert(mtm.empty()); } vector<int> renumberVec; int z; void renumber(){ renumberVec.push_back(-300000000); for(auto s: segment){ renumberVec.push_back(s.l); renumberVec.push_back(s.r); } sort(renumberVec.begin(), renumberVec.end()); renumberVec.erase(unique(renumberVec.begin(), renumberVec.end()), renumberVec.end()); z = renumberVec.size(); } inline int g(int x){ return upper_bound(renumberVec.begin(), renumberVec.end(), x) - renumberVec.begin() - 1; } int pnt = 0; void ODCinit(){ treeA.init(1, 0, z-1); treeB.init(1, 0, z-1); } void ODC(int l, int r, vector<Segment>& vec){ treeA.save(); treeB.save(); vector<Segment> lv, rv; int m = (l+r)/2; for(Segment s: vec){ if(s.s <= l && r <= s.e){ if(s.a == 1) treeA.rangeMax(1, 0, z-1, g(s.l), g(s.r)-1, s.b); else treeB.rangeMax(1, 0, z-1, g(s.l), g(s.r)-1, s.b); } else{ if(s.s <= m) lv.push_back(s); if(m < s.e) rv.push_back(s); } } if(l==r){ while(pnt < q && qvec[pnt].t == l){ Query query = qvec[pnt++]; // printf("%d: %d %d\n", pnt, treeA.getVal(1, 0, z-1, g(query.x)), treeB.getVal(1, 0, z-1, g(query.x))); ans[query.idx] = max(treeA.getVal(1, 0, z-1, g(query.x)) + query.x, treeB.getVal(1, 0, z-1, g(query.x)) - query.x); } return; } if(pnt < q && qvec[pnt].t <= m) ODC(l, m, lv); if(pnt < q && qvec[pnt].t <= r) ODC(m+1, r, rv); treeA.undo(); treeB.undo(); } void output(){ for(int i=1; i<=q; i++){ printf("%d\n", ans[i] > 100000000 ? -1 : ans[i]); } }

Compilation message (stderr)

new_home.cpp: In function 'void input()':
new_home.cpp:115:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  115 |     scanf("%d %d %d", &n, &k, &q);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
new_home.cpp:118:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  118 |         scanf("%d %d %d %d", &x, &t, &a, &b);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
new_home.cpp:126:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  126 |         scanf("%d %d", &l, &y);
      |         ~~~~~^~~~~~~~~~~~~~~~~
#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...