QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#557076#360. Cultivationmakrav0 1ms3876kbC++2013.8kb2024-09-11 02:11:092024-09-11 02:11:09

Judging History

你现在查看的是最新测评结果

  • [2024-09-11 02:11:09]
  • 评测
  • 测评结果:0
  • 用时:1ms
  • 内存:3876kb
  • [2024-09-11 02:11:09]
  • 提交

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++) {
        for (int j = i + 1; j < n; j++) {
            bool gpp = true;
            for (int k = 0; k < n; k++) {
                if (k==i||k==j)continue;
                if ((a[k].first - a[i].first) * (a[k].first - a[j].first) <= 0 && (a[k].second - a[i].second) * (a[k].second - a[j].second) <= 0) {
                    gpp = false;
                    break;
                }
            }
            gp[i][j]=gpp;
        }
    }
    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});
            }
        }
    }
    // for (auto &u : a) cout << u.first << ' ' << u.second << '\n';
    // for (auto &u : gps) {
    //     cout << u.first << ' ' << u.second << '\n';
    // }
    //return;
    // 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;
}

詳細信息

Subtask #1:

score: 0
Wrong Answer

Test #1:

score: 5
Accepted
time: 1ms
memory: 3856kb

input:

2 4
2
1 1
1 4

output:

3

result:

ok single line: '3'

Test #2:

score: 5
Accepted
time: 0ms
memory: 3640kb

input:

4 1
1
2 1

output:

3

result:

ok single line: '3'

Test #3:

score: 5
Accepted
time: 0ms
memory: 3512kb

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: 3584kb

input:

2 2
1
1 2

output:

2

result:

ok single line: '2'

Test #5:

score: 0
Wrong Answer
time: 0ms
memory: 3632kb

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: 3876kb

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%