QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#50687#1272. Dynamic Convex Hullckiseki#AC ✓529ms47848kbC++4.2kb2022-09-28 17:05:202022-09-28 17:05:21

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-09-28 17:05:21]
  • 评测
  • 测评结果:AC
  • 用时:529ms
  • 内存:47848kb
  • [2022-09-28 17:05:20]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
using lld = int64_t;
static constexpr lld mINF = numeric_limits<lld>::min();

struct L {
    lld a, b;
    int id;
    L(): a(8787), b(8787), id(-1) {}
    L(lld a_, lld b_, int id_)
        : a(a_), b(b_), id(id_) {}
    lld at(int x) const {
        lld dx = x - a;
        return -(dx * dx * dx * dx + b);
    }
    friend ostream &operator<<(ostream &os, const L &ln) {
        return os << "(x - " << ln.a << ")^4 + " << ln.b;
    }
};

class LC {
    int n;
    vector<L> nodes;
    static int lc(int x) { return 2 * x + 1; }
    static int rc(int x) { return 2 * x + 2; }

    vector<pair<int, L>> history;
    void assign(int id, L ln) {
        history.emplace_back(id, nodes[id]);
        nodes[id] = ln;
    }
    void insert(int l, int r, int id, L ln) {
        if (nodes[id].id == -1) {
            assign(id, ln);
            return;
        }
        const int m = (l + r) >> 1;
        bool atLeft = nodes[id].at(l) < ln.at(l);
        if (nodes[id].at(m) < ln.at(m)) {
            atLeft ^= 1;
            auto tmp = nodes[id];
            assign(id, ln);
            ln = tmp;
        }
        if (r - l == 1) return;
        if (atLeft) insert(l, m, lc(id), ln);
        else insert(m, r, rc(id), ln);
    }
    lld query(int l, int r, int id, int x) const {
        lld ret = mINF;
        if (nodes[id].id != -1)
            ret = nodes[id].at(x);
        if (r - l == 1) return ret;
        const int m = (l + r) >> 1;
        if (x < m)
            return max(ret, query(l, m, lc(id), x));
        return max(ret, query(m, r, rc(id), x));
    }
public:
    LC(int n_) : n(n_), nodes(n * 4) {}
    void insert(L ln) { insert(0, n, 0, ln); }
    lld query(int x) const { return query(0, n, 0, x); }
    size_t commit() const { return history.size(); }
    void restore(size_t commit_id) {
        while (history.size() > commit_id) {
            auto [id, v] = history.back();
            nodes[id] = v;
            history.pop_back();
        }
    }
} lct(50005);

class SGT {
    int n;
    vector<vector<L>> nodes;
    vector<int> que;

    static int lc(int x) { return 2 * x + 1; }
    static int rc(int x) { return 2 * x + 2; }

    void add(int ql, int qr, int l, int r, int id, L ln) {
        if (qr <= l or r <= ql) return;
        if (ql <= l and r <= qr) {
            nodes[id].push_back(ln);
            return;
        }
        int m = (l + r) >> 1;
        add(ql, qr, l, m, lc(id), ln);
        add(ql, qr, m, r, rc(id), ln);
    }
    void solve(int l, int r, int id) const {
        auto h = lct.commit();
        for (const auto &ln : nodes[id])
            lct.insert(ln);
        if (r - l == 1) {
            if (que[l] != -1) {
                auto v = lct.query(que[l]);
                if (v == mINF) v = 1;
                cout << -v << '\n';
            }
            lct.restore(h);
            return;
        }
        int m = (l + r) >> 1;
        solve(l, m, lc(id));
        solve(m, r, rc(id));
        lct.restore(h);
    }
public:
    SGT(int n_) : n(n_), nodes(n << 2), que(n, -1) {}
    void add(int l, int r, L ln) {
        add(l, r, 0, n, 0, ln);
    }
    void query(int i, int x) { que[i] = x; }
    void solve() const { solve(0, n, 0); }
};

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int t; cin >> t;
    while (t--) {
        int n, m;
        cin >> n >> m;
        vector<int> last(n + 1);

        vector<L> f(n + 1);
        for (int i = 1; i <= n; i++) {
            cin >> f[i].a >> f[i].b;
            f[i].id = i;
        }
        SGT sgt(m);

        for (int i = 0; i < m; i++) {
            int op;
            cin >> op;
            if (op == 1) {
                n = n + 1;
                last.push_back(i);
                lld a, b; cin >> a >> b;
                f.emplace_back(a, b, n);
            } else if (op == 2) {
                int x;
                cin >> x;
                sgt.add(last[x], i, f[x]);
                last[x] = -1;
            } else if (op == 3) {
                int x; cin >> x;
                sgt.query(i, x);
            }
        }

        for (int i = 1; i <= n; i++)
            if (last[i] != -1)
                sgt.add(last[i], m, f[i]);

        sgt.solve();
    }
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 3ms
memory: 7704kb

input:

1
2 8
3 9
6 100
3 4
2 1
3 4
1 1 1
3 4
2 2
2 3
3 4

output:

10
116
82
-1

result:

ok 4 lines

Test #2:

score: 0
Accepted
time: 529ms
memory: 47848kb

input:

5
100000 100000
39858 403048304064108142
6205 947055477496917683
788 911049878617783635
4261 626046370039242987
25008 685663359245704160
2202 848160200813297060
6216 289413959649340862
13189 722639235230562920
14820 749131972848517338
40221 716370580825502902
43025 222416883111096081
239 67541747335...

output:

105232514047244
112754306318445
54986177051691
74963972949549
118945174103964
69834459127665
33854058398778
275290771453117
65113537128811
45299248387930
51716327598553
68877950911521
135565157115804
288717635366668
10159612877616
161717641191962
161420883029513
72741135915164
109027638283771
179113...

result:

ok 355519 lines