QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#598463#9434. Italian Cuisineucup-team133#WA 0ms3544kbC++237.1kb2024-09-28 22:00:222024-09-28 22:00:25

Judging History

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

  • [2024-09-28 22:00:25]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:3544kb
  • [2024-09-28 22:00:22]
  • 提交

answer

#include <bits/stdc++.h>
#ifdef LOCAL
#include <debug.hpp>
#else
#define debug(...) void(0)
#endif

template <class T> std::istream& operator>>(std::istream& is, std::vector<T>& v) {
    for (auto& e : v) {
        is >> e;
    }
    return is;
}

template <class T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    for (std::string_view sep = ""; const auto& e : v) {
        os << std::exchange(sep, " ") << e;
    }
    return os;
}

template <class T, class U = T> bool chmin(T& x, U&& y) {
    return y < x and (x = std::forward<U>(y), true);
}

template <class T, class U = T> bool chmax(T& x, U&& y) {
    return x < y and (x = std::forward<U>(y), true);
}

template <class T> void mkuni(std::vector<T>& v) {
    std::ranges::sort(v);
    auto result = std::ranges::unique(v);
    v.erase(result.begin(), result.end());
}

template <class T> int lwb(const std::vector<T>& v, const T& x) {
    return std::distance(v.begin(), std::ranges::lower_bound(v, x));
}

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
constexpr int bsf_constexpr(unsigned int n) {
    int x = 0;
    while (!(n & (1 << x))) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

}  // namespace internal

}  // namespace atcoder

namespace atcoder {

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
  public:
    segtree() : segtree(0) {}
    explicit segtree(int n) : segtree(std::vector<S>(n, e())) {}
    explicit segtree(const std::vector<S>& v) : _n(int(v.size())) {
        log = internal::ceil_pow2(_n);
        size = 1 << log;
        d = std::vector<S>(2 * size, e());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) const {
        assert(0 <= p && p < _n);
        return d[p + size];
    }

    S prod(int l, int r) const {
        assert(0 <= l && l <= r && r <= _n);
        S sml = e(), smr = e();
        l += size;
        r += size;

        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }

    S all_prod() const { return d[1]; }

    template <bool (*f)(S)> int max_right(int l) const {
        return max_right(l, [](S x) { return f(x); });
    }
    template <class F> int max_right(int l, F f) const {
        assert(0 <= l && l <= _n);
        assert(f(e()));
        if (l == _n) return _n;
        l += size;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, d[l]))) {
                while (l < size) {
                    l = (2 * l);
                    if (f(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*f)(S)> int min_left(int r) const {
        return min_left(r, [](S x) { return f(x); });
    }
    template <class F> int min_left(int r, F f) const {
        assert(0 <= r && r <= _n);
        assert(f(e()));
        if (r == 0) return 0;
        r += size;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(d[r], sm))) {
                while (r < size) {
                    r = (2 * r + 1);
                    if (f(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

}  // namespace atcoder

using ll = long long;

using namespace std;

const int INF = 1e9 + 10;
const ll IINF = 2e18;

using S = array<ll, 2>;

S op(S l, S r) { return {min(l[0], r[0]), max(l[1], r[1])}; }

S e() { return {IINF, -IINF}; }

void solve() {
    int n;
    cin >> n;
    vector<int> t(n), c(n);
    for (int i = 0; i < n; i++) cin >> t[i] >> c[i];

    if (n <= 2) {
        cout << 0 << "\n";
        return;
    }
    for (int i = 0; i + 2 < n; i++) {
        if (t[i] == t[i + 1] and t[i + 1] == t[i + 2]) {
            cout << -1 << "\n";
            return;
        }
    }

    auto tmp = c;
    mkuni(tmp);
    vector<int> d(n);
    for (int i = 0; i < n; i++) d[i] = lwb(tmp, c[i]);
    int len = d.size();
    atcoder::segtree<S, op, e> seg(len);
    vector<int> alive;

    auto check = [&](ll v) -> bool {
        int other = -1;
        for (int i = 1; i < n; i++) {
            if (v * (t[i] - t[i - 1]) >= abs(c[i] - c[i - 1])) continue;
            if (other == -1 or v * (t[i] - t[other]) >= abs(c[i] - c[other])) {
                other = i - 1;
            } else {
                return false;
            }
        }
        return true;
        // bool seq = true;
        // for (int i = 1; i < n; i++) {
        //     bool ok = seq;
        //     ll x = c[i] - v * t[i], y = c[i] + v * t[i];
        //     {
        //         ll val = seg.prod(0, d[i])[1];
        //         if (x <= val) ok = true;
        //     }
        //     {
        //         ll val = seg.prod(d[i], n)[0];
        //         if (val <= y) ok = true;
        //     }
        //     bool pre = (v * (t[i] - t[i - 1]) >= abs(c[i] - c[i - 1]));
        //     if (not pre) {
        //         seq = false;
        //         for (int i : alive) seg.set(d[i], e());
        //         alive.clear();
        //     }
        //     if (ok) {
        //         ll X = c[i - 1] - v * t[i - 1], Y = c[i - 1] + v * t[i - 1];
        //         auto cur = seg.get(d[i - 1]);
        //         seg.set(d[i - 1], {min(cur[0], Y), max(cur[1], X)});
        //         alive.emplace_back(i - 1);
        //     }
        //     if (not seq and alive.empty()) return false;
        // }
        // for (int i : alive) seg.set(d[i], e());
        // bool res = seq or not alive.empty();
        // alive.clear();
        // return res;
    };

    int lb = -1, ub = INF;
    while (ub - lb > 1) {
        int mid = (lb + ub) >> 1;
        (check(mid) ? ub : lb) = mid;
    }

    cout << (ub == INF ? -1 : ub) << "\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int T;
    cin >> T;
    for (; T--;) solve();
    return 0;
}

詳細信息

Test #1:

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

input:

3
5
1 1 1
0 0
1 0
5 0
3 3
0 5
6
2 4 1
2 0
4 0
6 3
4 6
2 6
0 3
4
3 3 1
3 0
6 3
3 6
0 3

output:

-1
1
0

result:

wrong answer 1st numbers differ - expected: '5', found: '-1'