QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#282481#6420. Certain Scientific RailgunjrjyyWA 1ms3632kbC++204.2kb2023-12-12 10:23:102023-12-12 10:23:10

Judging History

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

  • [2023-12-12 10:23:10]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:3632kb
  • [2023-12-12 10:23:10]
  • 提交

answer

#include <bits/stdc++.h>

using i64 = long long;

constexpr i64 inf = 1e18;

template <typename T, typename Cmp = std::less<T>>
struct RMQ {
    const Cmp cmp{};
    int n;
    std::vector<std::vector<T>> a;
    RMQ() = default;
    RMQ(const std::vector<T> &v) {
        init(v);
    }
    RMQ(const std::vector<T> &v, const Cmp &cmp_) : cmp{cmp_} {
        init(v);
    }
    void init(const std::vector<T> &ini) {
        n = int(ini.size());
        int lg = std::__lg(n);
        a.assign(lg + 1, std::vector<T>(n));
        a[0] = ini;
        for (int i = 0; i < lg; ++i) {
            for (int j = 0; j <= n - (2 << i); ++j) {
                a[i + 1][j] = std::min(a[i][j], a[i][j + (1 << i)], cmp);
            }
        }
    }
    T operator()(int l, int r) const {
        int k = std::__lg(r - l);
        return std::min(a[k][l], a[k][r - (1 << k)], cmp);
    }
};

void solve() {
    int n;
    std::cin >> n;

    std::vector<int> x(n), y(n);
    for (int i = 0; i < n; ++i) {
        std::cin >> x[i] >> y[i];
    }
    x.push_back(0);
    y.push_back(0);
    ++n;

    std::vector<int> pos, neg{n - 1};
    for (int i = 0; i < n; ++i) {
        if (x[i] >= 0) {
            pos.push_back(i);
        } else {
            neg.push_back(i);
        }
    }

    i64 ans = inf;
    auto work = [&]() {
        auto get = [&](const std::vector<int> &id) {
            std::vector<int> v;
            for (auto i : id) {
                v.push_back(std::abs(x[i]));
            }
            std::sort(v.begin(), v.end());
            v.erase(std::unique(v.begin(), v.end()), v.end());

            std::vector<int> l(v.size() + 1), r(v.size() + 1);
            for (auto i : id) {
                int nx = std::lower_bound(v.begin(), v.end(), std::abs(x[i])) - v.begin();
                l[nx] = std::min(l[nx], y[i]);
                r[nx] = std::max(r[nx], y[i]);
            }
            for (int i = int(v.size()) - 1; i >= 0; --i) {
                l[i] = std::min(l[i], l[i + 1]);
                r[i] = std::max(r[i], r[i + 1]);
            }
            return std::make_tuple(v, l, r);
        };
        auto [pv, pl, pr] = get(pos);
        auto [nv, nl, nr] = get(neg);

        std::array<RMQ<i64>, 4> rmq;
        for (auto s : {0, 1, 2, 3}) {
            std::vector<i64> f(nv.size());
            for (int i = 0; i < int(nv.size()); ++i) {
                f[i] = i64(nv[i]) - s % 2 * nl[i + 1] + s / 2 * nr[i + 1];
            }
            rmq[s].init(f);
        }
        for (int i = 0, jl = 0, jr = 0, kl = 0, kr = 0; i < int(pv.size()); ++i) {
            while (jl < int(nv.size()) && pl[i + 1] > nl[jl + 1]) {
                ++jl;
            }
            while (kl < int(nv.size()) && pl[i + 1] >= nl[kl + 1]) {
                ++kl;
            }
            while (jr < int(nv.size()) && pr[i + 1] < nr[jr + 1]) {
                ++jr;
            }
            while (kr < int(nv.size()) && pr[i + 1] <= nr[kr + 1]) {
                ++kr;
            }
            for (auto s : {0, 1, 2, 3}) {
                int ql = std::max(s % 2 * jl, s / 2 * jr);
                int qr = std::min(s % 2 ? int(nv.size()) : kl, s / 2 ? int(nv.size()) : kr);
                if (ql < qr) {
                    i64 res =
                        rmq[s ^ 3](ql, qr) + pv[i] + nv[ql] - s % 2 * pl[i + 1] + s / 2 * pr[i + 1];
                    ans = std::min(ans, res);
                }
            }
        }
    };
    for (auto a : {-1, 1}) {
        for (auto b : {-1, 1}) {
            for (int i = 0; i < n; ++i) {
                if (x[i] * a > 0) {
                    x[i] *= 2;
                }
                if (y[i] * b > 0) {
                    y[i] *= 2;
                }
            }
            work();
            for (int i = 0; i < n; ++i) {
                if (x[i] * a > 0) {
                    x[i] /= 2;
                }
                if (y[i] * b > 0) {
                    y[i] /= 2;
                }
            }
        }
    }

    std::cout << ans << "\n";
}

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    int t;
    std::cin >> t;

    while (t--) {
        solve();
    }

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3632kb

input:

3
2
0 1
1 0
4
1 1
-3 -3
4 -4
-2 2
4
1 100
3 100
-100 1
3 -100

output:

0
8
4

result:

ok 3 number(s): "0 8 4"

Test #2:

score: -100
Wrong Answer
time: 1ms
memory: 3552kb

input:

120
4
11 11
-22 -22
33 -33
-44 44
4
-11 11
22 -22
-33 -33
44 44
4
-11 -11
22 22
-33 33
44 -44
4
11 -11
-22 22
33 33
-44 -44
4
-11 11
22 -22
33 33
-44 -44
4
11 11
-22 -22
-33 33
44 -44
4
11 -11
-22 22
-33 -33
44 44
4
-11 -11
22 22
33 -33
-44 44
4
1 1
-2 -2
3 -3
-4 4
4
-1 1
2 -2
-3 -3
4 4
4
-1 -1
2 2
...

output:

99
99
99
99
99
99
99
99
9
9
9
9
9
9
9
9
5
5
5
5
5
5
5
5
4
4
4
4
4
5
5
4
0
0
0
0
0
0
0
0
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
12
12
12
12
12
12
12
12
0
0
0
0
0
0
0
0
13
11
11
13
11
11
11
11
116
111
111
116
111
111
111
111
300
300
300
300
300
300
300
300
5
5
5
5
5
5
5
5
2
2
2
2
2
2
2
2
48
48
48
48
48
48
48...

result:

wrong answer 30th numbers differ - expected: '4', found: '5'