QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#557068 | #360. Cultivation | makrav | 0 | 0ms | 3668kb | C++20 | 13.9kb | 2024-09-11 01:58:42 | 2024-09-11 01:58:42 |
answer
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
#define pb push_back
#define ff first
#define sc second
#define int ll
const int INF = 1000000000000;
void solve() {
int h, w, n; cin >> h >> w >> n;
vector<pair<int, int>> a(n);
for (int i = 0; i < n; i++) cin >> a[i].ff >> a[i].sc;
vector<vector<bool>> gp(n, vector<bool>(n, false));
sort(all(a), [](pair<int, int> x, pair<int, int> y) {
return x.second < y.second;
});
for (int i = 0; i < n; i++) {
vector<vector<vector<int>>> pts(2, vector<vector<int>>(2));
for (int j = 0; j < n; j++) {
if (j == i) continue;
pts[(a[j].second >= a[i].second)][(a[j].first >= a[i].first)].pb(j);
}
for (int j = 0; j < 2; j++) reverse(all(pts[0][j]));
for (int i1 = 0; i1 < 2; i1++) {
for (int j = 0; j < 2; j++) {
int mind = INF;
for (int k = 0; k < pts[i1][j].size(); k++) {
if (abs(a[pts[i1][j][k]].first - a[i].first) < mind) {
gp[i][pts[i1][j][k]] = true;
mind = abs(a[pts[i1][j][k]].first - a[i].first);
}
}
}
}
}
vector<pair<int, int>> gps;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (gp[i][j]) {
//cout << i << ' ' << j << '\n';
gps.pb({i, j});
}
}
}
// all above -- correct (i think)
vector<ll> delta(sz(gps));
vector<int> is_delta_correct(sz(gps));
for (int i = 0; i < sz(gps); i++) {
ll max_up = 0, min_d = h + 1;
int mxy = max(a[gps[i].first].first, a[gps[i].second].first), mny = min(a[gps[i].first].first, a[gps[i].second].first);
for (int j = 0; j < n; j++) {
if (a[gps[i].first].second < a[j].second && a[j].second < a[gps[i].second].second) {
if (a[j].first > mxy) min_d = min(min_d, (ll)a[j].first);
else {
assert(a[j].first < mny);
max_up = max(max_up, (ll)a[j].first);
}
}
}
if (min_d == h + 1 && max_up == 0) delta[i] = INF;
else if (min_d != h + 1 && max_up != 0) delta[i] = (min_d - max_up - 1);
else {
if (min_d != h + 1) {
is_delta_correct[i] = 1;
delta[i] = min_d - 1;
} else {
is_delta_correct[i] = 2;
delta[i] = h - max_up;
}
}
}
// all above -- probably correct ..)
vector<int> never_left(n), never_right(n);
vector<ll> lol_left(n), lol_right(n);
vector<int> type_left(n), type_right(n);
for (int i = 0; i < n; i++) {
{
// left
int max_up = 0, min_d = h + 1;
for (int j = 0; j < n; j++) {
if (a[j].second < a[i].second) {
if (a[j].first == a[i].first) {
never_left[i] = 1;
break;
}
if (a[j].first < a[i].first) max_up = max(max_up, a[j].first);
else min_d = min(min_d, a[j].first);
}
}
if (min_d == h + 1 && max_up == 0) lol_left[i] = INF;
else if (min_d != h + 1 && max_up != 0) lol_left[i] = min_d - max_up;
else {
if (min_d != h + 1) {
type_left[i] = 1;
lol_left[i] = min_d - 1;
} else {
type_left[i] = 2;
lol_left[i] = h - max_up;
}
}
}
{
// right
int max_up = 0, min_d = h + 1;
for (int j = 0; j < n; j++) {
if (a[j].second > a[i].second) {
if (a[j].first == a[i].first) {
never_right[i] = 1;
break;
}
if (a[j].first < a[i].first) max_up = max(max_up, a[j].first);
else min_d = min(min_d, a[j].first);
}
}
if (min_d == h + 1 && max_up == 0) lol_right[i] = INF;
else if (min_d != h + 1 && max_up != 0) lol_right[i] = min_d - max_up;
else {
if (min_d != h + 1) {
type_right[i] = 1;
lol_right[i] = min_d - 1;
} else {
type_right[i] = 2;
lol_right[i] = h - max_up;
}
}
}
}
// check this block above
vector<int> ord_left(n), ord_right(n);
iota(all(ord_left), 0); iota(all(ord_right), 0);
sort(all(ord_left), [&](int i, int j) {
return a[i].second < a[j].second;
});
sort(all(ord_right), [&](int i, int j) {
return a[i].second > a[j].second;
});
vector<int> pos_left(n), pos_right(n);
for (int i = 0; i < n; i++) {
pos_left[ord_left[i]] = i;
pos_right[ord_right[i]] = i;
}
vector<int> ups;
for (int i = 0; i < n; i++) ups.pb(a[i].first - 1);
// part above probably correct
vector<int> alds;
for (int i = 0; i < sz(gps); i++) {
alds.pb(a[gps[i].second].second - a[gps[i].first].second - 1);
}
sort(all(alds));
alds.resize(unique(all(alds)) - alds.begin());
map<int, int> pos;
for (int i = 0; i < sz(alds); i++) pos[alds[i]] = i;
vector<int> ind_mid(sz(gps));
for (int i = 0; i < sz(gps); i++) ind_mid[i] = pos[a[gps[i].second].second - a[gps[i].first].second - 1];
// part above probably correct
vector<int> ordp1(sz(gps)) /* order by delta of basic y values */, ordp2(sz(gps)) /* order by delta of second y values */;
vector<int> vals(sz(gps)), W(sz(gps));
for (int i = 0; i < sz(gps); i++) {
vals[i] = abs(a[gps[i].first].first - a[gps[i].second].first);
W[i] = a[gps[i].second].second - a[gps[i].first].second;
}
iota(all(ordp1), 0);
sort(all(ordp1), [&](int i, int j){
return vals[i] < vals[j];
});
iota(all(ordp2), 0);
sort(all(ordp2), [&](int i, int j) {
return delta[i] < delta[j];
});
vector<int> YS;
for (int i =0;i<n;i++)YS.pb(a[i].first);
sort(all(YS));
int MX=0;
for (int i=1;i<n;i++){
MX=max(MX,YS[i]-YS[i-1]-1);
}
// fuck
int need_down = INF;
for (int i = 0; i < n; i++) need_down = min(need_down, h - a[i].first);
auto solve = [&](int up) -> long long {
// returns minimal answer with current up value
vector<pair<int, int>> lefts, rights;
vector<int> used_left(n, 0), used_right(n, 0), cnt_mid(sz(alds));
vector<pair<int, int>> start_mid, endd_mid, endd_mid_fuck;
for (int i = 0; i < n; i++) {
{
if (never_left[i]) continue;
if (type_left[i] == 0) {
if (lol_left[i] - 1 <= up) continue;
lefts.pb({lol_left[i] - 1 - up, pos_left[i]});
used_left[pos_left[i]] = 1;
} else if (type_left[i] == 1) {
if (up >= lol_left[i]) continue;
used_left[pos_left[i]] = 1;
} else {
used_left[pos_left[i]] = 1;
lefts.pb({lol_left[i], pos_left[i]});
}
}
{
if (never_right[i]) continue;
if (type_right[i] == 0) {
if (lol_right[i] - 1 <= up) continue;
rights.pb({lol_right[i] - 1 - up, pos_right[i]});
used_right[pos_right[i]] = 1;
} else if (type_right[i] == 1) {
if (up >= lol_right[i]) continue;
used_right[pos_right[i]] = 1;
} else {
used_right[pos_right[i]] = 1;
rights.pb({lol_right[i], pos_right[i]});
}
if (lol_right[i] - 1 <= up) {
continue;
}
}
}
sort(all(lefts)); sort(all(rights));
int pmax_left = -1, pmax_right = -1, pmid = -1;
auto update_left = [&]() {
while (pmax_left >= 0 && !used_left[pmax_left]) pmax_left--;
};
auto update_right = [&]() {
while (pmax_right >= 0 && !used_right[pmax_right]) pmax_right--;
};
auto update_mid = [&]() {
while (pmid >= 0 && cnt_mid[pmid] <= 0) pmid--;
};
for (int i = 0; i < n; i++) {
if (used_left[i]) pmax_left = i;
if (used_right[i]) pmax_right = i;
}
vector<int> E0;
for (int i = 0; i < sz(gps); i++) {
int j = ordp2[i];
if (is_delta_correct[j] == 0) {
endd_mid.pb({ind_mid[j], max(0ll, delta[j] - up)});
} else if (is_delta_correct[j] == 1) {
if (up >= delta[j]) {
E0.pb(ind_mid[j]);
}
} else {
endd_mid_fuck.pb({ind_mid[j], delta[j]});
}
start_mid.pb({ind_mid[ordp1[i]], max(0ll, vals[ordp1[i]] - up)});
}
// for (int i = 0; i < sz(gps); i++) {
// if (is_delta_correct[ordp2[i]]) {
// endd_mid.pb({ind_mid[ordp2[i]], delta[ordp2[i]]});
// } else {
// }
// if (delta[ordp2[i]] > up) endd_mid.pb({ind_mid[ordp1[i]], delta[ordp2[i]] - up});
// }
int ind_start = 0, ind_endd = 0, ind_endd_fuck = 0, ind_left = 0, ind_right = 0;
for (int F : E0) {
cnt_mid[F]--;
}
while (ind_start < sz(start_mid) && start_mid[ind_start].second == 0) {
cnt_mid[start_mid[ind_start].first]++;
ind_start++;
}
while (ind_endd_fuck < sz(endd_mid_fuck) && endd_mid_fuck[ind_endd_fuck].second == 0) {
cnt_mid[endd_mid_fuck[ind_endd_fuck].first]--;
ind_endd_fuck++;
}
while (ind_endd < sz(endd_mid) && endd_mid[ind_endd].second == 0) {
cnt_mid[endd_mid[ind_endd].first]--;
ind_endd++;
}
while (ind_left < sz(lefts) && lefts[ind_left].first == 0) {
used_left[lefts[ind_left].second] = 0;
ind_left++;
}
while (ind_right < sz(rights) && rights[ind_right].first == 0) {
used_right[rights[ind_right].second] = 0;
ind_right++;
}
update_left(); update_right();
for (int i = 0; i < sz(alds); i++) {
if (cnt_mid[i] > 0) pmid = i;
}
int NEW_NEED = max(need_down, MX-up);
int A = 4 * INF;
int pl = (pmax_left == -1 ? 0 : a[ord_left[pmax_left]].second - 1), pr = (pmax_right == -1 ? 0 : w - a[ord_right[pmax_right]].second),
pm = (pmid == -1 ? 0 : alds[pmid]);
int pmnt=-1;
//cout << up << " start shit " << pl << ' ' << pr << ' ' << pm << '\n';
while (ind_start < sz(start_mid) || ind_endd_fuck < sz(endd_mid_fuck) || ind_left < sz(lefts) || ind_right < sz(rights) || ind_endd < sz(endd_mid)) {
int mnt = 4 * INF;
if (ind_start < sz(start_mid)) mnt = min(mnt, start_mid[ind_start].second);
if (ind_left < sz(lefts)) mnt = min(mnt, lefts[ind_left].first);
if (ind_right < sz(rights)) mnt = min(mnt, rights[ind_right].first);
if (ind_endd < sz(endd_mid)) mnt = min(mnt, endd_mid[ind_endd].second);
if (ind_endd_fuck < sz(endd_mid_fuck)) mnt = min(mnt, endd_mid_fuck[ind_endd_fuck].second);
while (ind_start < sz(start_mid) && start_mid[ind_start].second == mnt) {
cnt_mid[start_mid[ind_start].first]++;
ind_start++;
}
while (ind_endd < sz(endd_mid) && endd_mid[ind_endd].second == mnt) {
cnt_mid[endd_mid[ind_endd].first]--;
ind_endd++;
}
while (ind_endd_fuck < sz(endd_mid_fuck) && endd_mid_fuck[ind_endd_fuck].second == mnt) {
cnt_mid[endd_mid_fuck[ind_endd_fuck].first]--;
ind_endd_fuck++;
}
while (ind_left < sz(lefts) && lefts[ind_left].first == mnt) {
used_left[lefts[ind_left].second] = 0;
ind_left++;
}
while (ind_right < sz(rights) && rights[ind_right].first == mnt) {
used_right[rights[ind_right].second] = 0;
ind_right++;
}
update_left(); update_mid(); update_right();
int cl = (pmax_left == -1 ? 0 : a[ord_left[pmax_left]].second - 1), cr = (pmax_right == -1 ? 0 : w - a[ord_right[pmax_right]].second),
cmid = (pmid == -1 ? 0 : alds[pmid]);
//cout << up << ' ' << mnt << ' ' << cl << ' ' << cr << ' ' << cmid << '\n';
if (mnt >= NEW_NEED) {
A = min(A, mnt + max(cl + cr, cmid));
if (mnt > NEW_NEED && pmnt <= NEW_NEED) {
A=min(A, NEW_NEED+max(pl+pr,pm));
}
}
pmnt=mnt;
pm=cmid;
pl=cl;
pr=cr;
}
return A + up;
};
ll ans = 4000000000;
for (int up : ups) {
ans = min(ans, solve(up));
}
cout << ans << '\n';
}
signed main() {
int tt = 1;
#ifdef LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
cin >> tt;
#else
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
#endif
while (tt--) {
solve();
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Subtask #1:
score: 0
Wrong Answer
Test #1:
score: 5
Accepted
time: 0ms
memory: 3560kb
input:
2 4 2 1 1 1 4
output:
3
result:
ok single line: '3'
Test #2:
score: 5
Accepted
time: 0ms
memory: 3628kb
input:
4 1 1 2 1
output:
3
result:
ok single line: '3'
Test #3:
score: 5
Accepted
time: 0ms
memory: 3580kb
input:
3 3 3 1 2 1 3 3 3
output:
3
result:
ok single line: '3'
Test #4:
score: 5
Accepted
time: 0ms
memory: 3572kb
input:
2 2 1 1 2
output:
2
result:
ok single line: '2'
Test #5:
score: 0
Wrong Answer
time: 0ms
memory: 3584kb
input:
4 4 10 4 2 2 3 2 4 4 1 1 2 2 1 4 3 3 3 3 1 1 4
output:
1
result:
wrong answer 1st lines differ - expected: '2', found: '1'
Subtask #2:
score: 0
Skipped
Dependency #1:
0%
Subtask #3:
score: 0
Skipped
Dependency #2:
0%
Subtask #4:
score: 0
Wrong Answer
Test #45:
score: 0
Wrong Answer
time: 0ms
memory: 3668kb
input:
1000000000 1000000000 17 822413671 70423910 260075513 431043546 300945721 793553248 142848049 163787897 392462410 831950868 699005697 111397300 444396260 130450496 642691616 595456084 467968916 463598810 159764248 611476406 929313754 539645102 365153650 964108073 906780716 373514044 970118116 655138...
output:
812905952
result:
wrong answer 1st lines differ - expected: '852626202', found: '812905952'
Subtask #5:
score: 0
Skipped
Dependency #4:
0%
Subtask #6:
score: 0
Skipped
Dependency #1:
0%