# |
Submission time |
Handle |
Problem |
Language |
Result |
Execution time |
Memory |
499252 |
2021-12-27T14:09:29 Z |
600Mihnea |
Golf (JOI17_golf) |
C++17 |
|
43 ms |
88000 KB |
#include <bits/stdc++.h>
using namespace std;
#define y1 ynot1
typedef long long ll;
typedef long double ld;
struct Box {
int xmin;
int xmax;
int ymin;
int ymax;
};
const int N = 100000 + 7;
const int INF = (int) 1e9 + 7;
int n;
int x1;
int y1;
int x2;
int y2;
Box boxes[N];
void normalization() {
map<int, int> mx, my;
for (int i = 0; i <= n + 1; i++) {
mx[boxes[i].xmin] = 0;
mx[boxes[i].xmax] = 0;
my[boxes[i].ymin] = 0;
my[boxes[i].ymax] = 0;
}
int c = 0;
for (auto &it : mx) {
it.second = ++c;
}
c = 0;
for (auto &it : my) {
it.second = ++c;
}
for (int i = 0; i <= n + 1; i++) {
boxes[i].xmin = mx[boxes[i].xmin];
boxes[i].xmax = mx[boxes[i].xmax];
boxes[i].ymin = my[boxes[i].ymin];
boxes[i].ymax = my[boxes[i].ymax];
}
}
struct Segment {
int where;
int low;
int high;
int e_low;
int e_high;
int dp;
};
/**
segment tree of lasts
**/
struct Node {
int mn;
int mx;
};
Node operator + (Node a, Node b) {
return {min(a.mn, b.mn), max(a.mx, b.mx)};
}
const Node non = {2 * N, 0};
Node segt1[8 * N];
Node lazy1[8 * N];
void push(int v, int tl, int tr) {
if (lazy1[v].mn == non.mn && lazy1[v].mx == non.mx) {
return;
}
segt1[v] = segt1[v] + lazy1[v];
if (tl < tr) {
lazy1[2 * v] = lazy1[2 * v] + lazy1[v];
lazy1[2 * v + 1] = lazy1[2 * v + 1] + lazy1[v];
}
lazy1[v] = non;
}
void updsegt1(int v, int tl, int tr, int l, int r, int x) {
push(v, tl, tr);
if (tr < l || r < tl) {
return;
}
if (l <= tl && tr <= r) {
lazy1[v] = lazy1[v] + Node{x, x};
push(v, tl, tr);
return;
}
int tm = (tl + tr) / 2;
updsegt1(2 * v, tl, tm, l, r, x);
updsegt1(2 * v + 1, tm + 1, tr, l, r, x);
segt1[v] = segt1[2 * v] + segt1[2 * v + 1];
}
void updsegt1(int l, int r, int x) {
if (l > r) {
return;
}
assert(1 <= l && l <= r && r <= 2 * (n + 2));
updsegt1(1, 1, 2 * (n + 2), l, r, x);
}
Node getsegt1(int v, int tl, int tr, int l, int r) {
push(v, tl, tr);
if (tr < l || r < tl) {
return non;
}
if (l <= tl && tr <= r) {
return segt1[v];
}
int tm = (tl + tr) / 2;
return getsegt1(2 * v, tl, tm, l, r) + getsegt1(2 * v + 1, tm + 1, tr, l, r);
}
Node getsegt1(int l, int r) {
return getsegt1(1, 1, 2 * (n + 2), l, r);
}
void clr() {
for (int i = 0; i < 8 * N; i++) {
segt1[i] = non;
lazy1[i] = non;
}
}
vector<vector<Segment>> segs;
vector<Segment> xSegs;
vector<Segment> ySegs;
bool cmpextlowX(int i, int j) {
return xSegs[i].low < xSegs[j].low;
}
bool cmpexthighX(int i, int j) {
return xSegs[i].high > xSegs[j].high;
}
bool cmpextY(int i, int j) {
return ySegs[i].where < ySegs[j].where;
}
bool cmp(int i, int j) {
return xSegs[i].e_low < xSegs[j].e_low;
}
void calculateextensions() {
for (int step = 1; step <= 2; step++) {
/// calculate x segs
for (int i = 0; i <= n + 1; i++) {
xSegs.push_back({boxes[i].ymin, boxes[i].xmin, boxes[i].xmax, 0, 2 * N, -1});
xSegs.push_back({boxes[i].ymax, boxes[i].xmin, boxes[i].xmax, 0, 2 * N, -1});
}
for (int i = 0; i <= n + 1; i++) {
swap(boxes[i].xmin, boxes[i].ymin);
swap(boxes[i].xmax, boxes[i].ymax);
}
swap(xSegs, ySegs);
}
assert((int) xSegs.size() == 2 * (n + 2));
assert((int) ySegs.size() == 2 * (n + 2));
for (int step = 1; step <= 2; step++) {
/// compute the extensions
{
vector<int> ordx(2 * (n + 2)), ordy;
iota(ordx.begin(), ordx.end(), 0);
ordy = ordx;
sort(ordx.begin(), ordx.end(), cmpextlowX);
sort(ordy.begin(), ordy.end(), cmpextY);
{
clr();
int ptr = 0;
for (int it = 0; it < 2 * (n + 2); it++) {
int i = ordx[it];
while (ptr < 2 * (n + 2) && ySegs[ordy[ptr]].where < xSegs[i].low) {
updsegt1(ySegs[ordy[ptr]].low + 1, ySegs[ordy[ptr]].high - 1, ySegs[ordy[ptr]].where);
ptr++;
}
xSegs[i].e_low = getsegt1(xSegs[i].where, xSegs[i].where).mx;
}
}
{
reverse(ordx.begin(), ordx.end()); /// optimization, daca nu merge, incearca cmpexthighX
reverse(ordy.begin(), ordy.end());
clr();
int ptr = 0;
for (int it = 0; it < 2 * (n + 2); it++) {
int i = ordx[it];
while (ptr < 2 * (n + 2) && ySegs[ordy[ptr]].where > xSegs[i].high) {
updsegt1(ySegs[ordy[ptr]].low + 1, ySegs[ordy[ptr]].high - 1, ySegs[ordy[ptr]].where);
ptr++;
}
xSegs[i].e_high = getsegt1(xSegs[i].where, xSegs[i].where).mn;
}
}
}
/// checker
for (auto &it : xSegs) {
assert(it.e_low <= it.low);
assert(it.high <= it.e_high);
}
swap(xSegs, ySegs);
}
segs.push_back(xSegs);
segs.push_back(ySegs);
}
queue<pair<int, int>> q;
bool deja[2][2 * N];
int done;
void addToQ(int type, int index, int value) {
done++;
deja[type][index] = 1;
assert(0 <= type && type < 2);
assert(0 <= index && index < (int) segs[type].size());
assert(segs[type][index].dp == -1);
segs[type][index].dp = value;
q.push({type, index});
}
struct Snode {
int index;
int where;
};
bool operator < (Snode a, Snode b) {
if (a.where != b.where) {
return a.where < b.where;
}
return a.index < b.index;
}
set<Snode> guys[2][8 * N];
vector<int> now;
set<int> ct;
int dn;
void addToSegt(int type, int v, int tl, int tr, int l, int r, Snode node) {
if (tr < l || r < tl) {
return;
}
if (l <= tl && tr <= r) {
dn += tr - tl + 1;
guys[type][v].insert(node);
return;
}
int tm = (tl + tr) / 2;
addToSegt(type, 2 * v, tl, tm, l, r, node);
addToSegt(type, 2 * v + 1, tm + 1, tr, l, r, node);
}
void del(int type, int v, int tl, int tr, int l, int r, int i) {
if (tr < i || i < tl) {
return;
}
while (!guys[type][v].empty()) {
auto it = guys[type][v].lower_bound({l, 0});
if (it == guys[type][v].end()) {
break;
}
if (it->where > r) {
break;
}
int j = it->index;
if (!deja[type][it->index]) {
now.push_back(it->index);
deja[type][it->index] = 1;
}
guys[type][v].erase(it);
}
if (tl == tr) {
return;
}
int tm = (tl + tr) / 2;
del(type, 2 * v, tl, tm, l, r, i);
del(type, 2 * v + 1, tm + 1, tr, l, r, i);
}
signed main() {
ios::sync_with_stdio(0); cin.tie(0);
///freopen ("input2", "r", stdin);
cin >> x1 >> y1 >> x2 >> y2;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> boxes[i].xmin >> boxes[i].xmax >> boxes[i].ymin >> boxes[i].ymax;
}
boxes[0].xmin = boxes[0].xmax = x1;
boxes[0].ymin = boxes[0].ymax = y1;
boxes[n + 1].xmin = boxes[n + 1].xmax = x2;
boxes[n + 1].ymin = boxes[n + 1].ymax = y2;
normalization(); /// do it later
calculateextensions();
if (n > 1000) {
/// exit(0); /// I wanted to measure the first part of the algorithm
}
addToQ(0, 0, 1);
addToQ(0, 1, 1);
addToQ(1, 0, 1);
addToQ(1, 1, 1);
for (int type = 0; type < 2; type++) {
for (int i = 0; i < 2 * (n + 2); i++) {
segs[type][i].e_low = max(segs[type][i].e_low, 1);
segs[type][i].e_high = min(segs[type][i].e_high, 2 * (n + 2));
dn = 0;
addToSegt(type, 1, 1, 2 * (n + 2), segs[type][i].e_low, segs[type][i].e_high, {i, segs[type][i].where});
}
ct.clear();
}
while (!q.empty()) {
// cout << done << "\n";
if (n > 1000 && done >= 15000) {
exit(0);
}
auto itQ = q.front();
q.pop();
int type = itQ.first;
int index = itQ.second;
int dp = segs[type][index].dp;
assert(2 * (n + 2) == (int) segs[type ^ 1].size());
now.clear();
del(type ^ 1, 1, 1, 2 * (n + 2), segs[type][index].e_low, segs[type][index].e_high, segs[type][index].where);
for (auto &j : now) {
addToQ(type ^ 1, j, segs[type][index].dp + 1);
}
}
for (auto &v : segs) {
for (auto &seg : v) {
assert(seg.dp != -1);
}
}
x2 = boxes[n + 1].xmin;
y2 = boxes[n + 1].ymin;
int sol = INF;
swap(x2, y2);
for (auto &v : segs) {
for (auto &seg : v) {
if (x2 == seg.where && seg.e_low <= y2 && y2 <= seg.e_high) {
sol = min(sol, seg.dp);
}
}
swap(x2, y2);
}
cout << sol << "\n";
return 0;
}
Compilation message
golf.cpp: In function 'void del(int, int, int, int, int, int, int)':
golf.cpp:311:9: warning: unused variable 'j' [-Wunused-variable]
311 | int j = it->index;
| ^
golf.cpp: In function 'int main()':
golf.cpp:380:9: warning: unused variable 'dp' [-Wunused-variable]
380 | int dp = segs[type][index].dp;
| ^~
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
43 ms |
87884 KB |
Output is correct |
2 |
Correct |
43 ms |
87992 KB |
Output is correct |
3 |
Incorrect |
41 ms |
88000 KB |
Output isn't correct |
4 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
43 ms |
87884 KB |
Output is correct |
2 |
Correct |
43 ms |
87992 KB |
Output is correct |
3 |
Incorrect |
41 ms |
88000 KB |
Output isn't correct |
4 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
43 ms |
87884 KB |
Output is correct |
2 |
Correct |
43 ms |
87992 KB |
Output is correct |
3 |
Incorrect |
41 ms |
88000 KB |
Output isn't correct |
4 |
Halted |
0 ms |
0 KB |
- |