QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#797906#9809. The Grand ContestLegend_dyWA 231ms3896kbC++235.3kb2024-12-03 20:41:152024-12-03 20:41:15

Judging History

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

  • [2024-12-03 20:41:15]
  • 评测
  • 测评结果:WA
  • 用时:231ms
  • 内存:3896kb
  • [2024-12-03 20:41:15]
  • 提交

answer

#include <bits/stdc++.h>
#define dbg(x) cout << #x "=" << (x) << ' '
#define ls (w << 1)
#define rs (w << 1 | 1)
#define int long long
// #define endl '\n'

using namespace std;
using ll = long long;
using pli = pair<ll, ll>;
using pll = pair<ll, ll>;

struct Node {
    int team, pbm;
    bool pass;
    ll time;
};

struct SegTree {
    vector<pli> tr; //{max, index}
    SegTree(int n) : tr(n << 2, {-2e18, 1e9}) {}
    pli merge(pli u, pli v) {
        if (u.first >= v.first) return u;
        return v;
    }
    void modify(int w, int l, int r, int pos, pli x) {
        if (l == r) {
            tr[w] = x;
            return;
        }
        int mid = (l + r) >> 1;
        if (pos <= mid)
            modify(ls, l, mid, pos, x);
        else
            modify(rs, mid + 1, r, pos, x);
        tr[w] = merge(tr[ls], tr[rs]);
    }
    pli ask(int w, int l, int r, int ql, int qr, ll mn) {
        if (r < ql || l > qr || tr[w].first < mn) return {-2e18, 1e9};
        if (l == r) return tr[w];
        int mid = (l + r) >> 1;
        pli res = ask(ls, l, mid, ql, qr, mn);
        if (res.first >= mn) return res;
        return ask(rs, mid + 1, r, ql, qr, mn);
    }
};

void solve() {
    ll n, p;
    cin >> n >> p;

    vector<Node> a(n);
    map<int, bool> canPass[3];
    for (int i = 0; i < n; i++) {
        cin >> a[i].team >> a[i].pbm >> a[i].time >> a[i].pass;
        if (a[i].pass) canPass[a[i].team][a[i].pbm] = 1;
    }

    vector<Node> b;
    vector<ll> t;
    ll cnt[3] = {0}, pnty[3] = {0};
    map<int, bool> hasPass[3];
    t.push_back(0);
    for (int i = 0; i < n; i++) {
        if (hasPass[a[i].team][a[i].pbm] || !canPass[a[i].team][a[i].pbm])
            continue;
        if (a[i].pass) {
            hasPass[a[i].team][a[i].pbm] = 1;
            cnt[a[i].team]++;
            pnty[a[i].team] += a[i].time;
            if (a[i].time != t.back()) {
                if (t.back() + 1 < a[i].time) {
                    t.push_back(t.back() + 1);
                    if(t.back() < a[i].time - 1)
                        t.push_back(a[i].time - 1);
                }
                t.push_back(a[i].time);
            }
            b.push_back(a[i]);
        } else {
            pnty[a[i].team] += p;
        }
    }
    t.push_back(t.back() + 1);
    if (cnt[1] != cnt[2] || cnt[1] == 0) {
        cout << -1 << endl;
        return;
    }
    int wer, ler;
    ll need;
    if (pnty[1] <= pnty[2]) {
        wer = 1;
        ler = 2;
        need = pnty[2] - pnty[1] + 1;
    } else {
        wer = 2;
        ler = 1;
        need = pnty[1] - pnty[2];
    }

    // dbg(cnt[1]); dbg(pnty[1]) << endl;
    // dbg(cnt[2]); dbg(pnty[2]) << endl;
    // dbg(need) << endl;

    int m = t.size(), j = 0;
    vector<vector<ll>> f(3, vector<ll>(m + 5));
    vector<vector<ll>> g(3, vector<ll>(m + 5));
    vector<ll> h(m + 5);
    vector<pll> seg(m + 5);
    for (int i = 0; i < b.size(); i++) {
        while (t[j] < b[i].time) j++;
        f[b[i].team][j] += b[i].time;
        g[b[i].team][j]++;
    }
    for (int i = m - 1; i >= 0; i--)
        for (int k = 1; k <= 2; k++) {
            g[k][i] += g[k][i + 1];
            f[k][i] += f[k][i + 1];
        }

    for (int i = 0; i < m; i++) {
        h[i] = t[i] * (g[wer][i] - g[ler][i]);
        h[i] -= f[wer][i] - f[ler][i];
    }

    // cout << "t : ";
    // for(auto tmp : t)
    //     cout << tmp << ' ';
    // cout << endl;

    ll ansL = -1, ansR = 2e18, x = 0, y = 0;
    j = b.size() - 1;
    SegTree tr(m + 5);
    for (int i = m - 1; i >= 0; i--) {
        // L = t[i]    (]
        // find the min seq of R  [)
        while (j >= 0 && b[j].time > t[i]) {
            if (b[j].team == wer) {
                x += b[j].time;
                y++;
            } else {
                x -= b[j].time;
                y--;
            }
            j--;
        }
        seg[i] = {x, y}; // x - y * R
        ll mx = x - y * t[i];
        if (i != m - 1 && t[i] <= t[i + 1] - 1)
            mx = max(mx, x - y * (t[i + 1] - 1));
        tr.modify(1, 0, m, i, {mx, i});

        // h[l] + x - R * y >= need
        // h[l] + mx >= need
        ll less = need - h[i];
        pli res = tr.ask(1, 0, m, i, m - 1, less);

        // dbg(i); dbg(t[i]); cout << "{" << seg[i].first << " " <<
        // seg[i].second << "} "; dbg(mx) << endl; dbg(less); dbg(need);
        // dbg(h[i]) << endl; dbg(res.first); dbg(res.second) << endl;

        if (res.first < less) continue;
        int pos = res.second; // t[pos] <= R < t[pos + 1]
        // dbg(pos) << endl;
        ll px = seg[pos].first, py = seg[pos].second;
        ll L = t[i], R = t[pos];
        // px - py * R >= less
        if (py < 0 && px - less < 0) {
            R = max(R, (less - px - py - 1) / -py);
        }
        // dbg(i); dbg(L); dbg(R) << endl;
        if (R - L <= ansR - ansL) {
            ansL = L;
            ansR = R;
        }
    }
    if (ansL == -1) {
        cout << -1 << endl;
    } else {
        cout << ansL << ' ' << ansR << endl;
    }
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T = 1;
    cin >> T;
    for (int tc = 1; tc <= T; tc++) {
        solve();
    }

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

2
6 20
1 1 60 0
2 2 60 0
2 2 120 1
1 2 180 1
1 2 180 0
2 2 300 1
2 20
1 1 300 1
2 2 300 1

output:

120 160
-1

result:

ok 3 number(s): "120 160 -1"

Test #2:

score: 0
Accepted
time: 231ms
memory: 3552kb

input:

400000
1 1
1 1000000000 1000000000000 1
1 1
2 1000000000 1 0
1 1
2 1 1000000000000 1
1 1
1 1 1000000000000 1
1 1
2 1000000000 1000000000000 0
1 1
2 1 1 0
1 1000000000000
2 1000000000 1 0
1 1000000000000
1 1 1 0
1 1000000000000
1 1 1 1
1 1000000000000
2 1000000000 1000000000000 0
1 1
1 1000000000 1 0...

output:

-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
...

result:

ok 400000 numbers

Test #3:

score: -100
Wrong Answer
time: 187ms
memory: 3896kb

input:

10000
4 542575683220
2 101300788 7308006925 1
1 604560531 257884671293 0
1 46911674 422781533607 0
2 10550533 771273976896 1
116 793781361888
1 819065134 15224463201 1
2 552573547 15992997563 1
2 424217 27032314690 0
2 70252887 41541882886 0
2 274093456 46129251985 0
1 458919850 46344406806 1
1 8416...

output:

-1
-1
-1
-1
-1
66660446969 904724933033
-1
-1
-1
-1
-1
-1
37226106549 311799565893
-1
-1
-1
-1
-1
-1
48301734080 375528816957
-1
-1
-1
459021288402 632610827258
-1
-1
-1
-1
-1
-1
-1
688320095661 898231263806
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
22824143484...

result:

wrong answer 65th numbers differ - expected: '218002244243', found: '228241434848'