QOJ.ac

QOJ

IDSubmission IDProblemHackerOwnerResultSubmit timeJudge time
#1571#398887#8074. Multiply Then PlusxxzxrobinyqcFailed.2025-02-21 15:13:082025-02-21 15:13:09

Details

Extra Test:

Invalid Input

input:

100 500000
269662414 483837043
399541094 137640677
519919328 730271537
149458846 52715668
417141038 279225185
809696186 22487492
291802763 714552538
89885236 360790227
936592999 525747978
384470819 986985480
272483276 946941121
347942726 648924035
730933712 526473733
796319654 46082379
309699268 378...

output:


result:

FAIL Integer parameter [name=r] equals to 24, violates the range [63, 100] (stdin, line 105)

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#398887#8074. Multiply Then PlusrobinyqcAC ✓3057ms464764kbC++204.3kb2024-04-25 19:28:192024-04-25 19:28:20

answer

// vjudge submission

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <tuple>
using namespace std;

using u32 = unsigned int;
using u64 = unsigned long long;
using i64 = long long;

// query type: x, l, r, ans(addr.)
using qrt = tuple<u32, u32, u32, u64*>; 

struct Line 
{
    u32 k, b;
    Line(u32 _k = 0, u32 _b = 0): k(_k), b(_b) { }
    bool operator<(const Line& t) const { return k < t.k; }
    u64 val(u64 x) { return k * x + b; }
};

struct Convex
{
    vector<Line> cv;
    u32 pos;

    Convex() { }
    Convex(Line x): cv(1u, x), pos() { }
    Convex(const vector<Line> &ls, const vector<Line> &rs): pos()
    {
        decltype(cv) tmp(ls.size() + rs.size());
        cv.reserve(tmp.size());
        merge(ls.begin(), ls.end(), rs.begin(), rs.end(), tmp.begin());
        int s = -1;
        for (auto i: tmp) {
            while (s > 0 && ((i64)i.b - (i64)cv[s].b) * (cv[s].k - cv[s - 1].k)
            >= ((i64)cv[s].b - (i64)cv[s - 1].b) * (i.k - cv[s].k)) {
                cv.pop_back(), --s;
            }
            cv.emplace_back(i), ++s;
        }
    }

    u64 ask(u64 x)
    {
        u64 ansp = cv[pos].val(x), ansn;
        while(pos < cv.size() - 1 && (ansn = cv[pos + 1].val(x)) > ansp) {
            pos++;
            ansp = ansn;
        }
        return ansp;
    }
};

class ConvexSegmentTree
{

public:
    ConvexSegmentTree() { }
    ConvexSegmentTree(const vector<pair<u32, Line>>& a): m(1), pos(a.size())
    {
        while (m < a.size()) m += m;
        t.resize(m * 2);
        for (u32 i = 0; i < a.size(); i++) pos[i] = a[i].first;
        sort(pos.begin(), pos.end());
        for (u32 i = 0; i < a.size(); i++) {
            t[lower_bound(pos.begin(), pos.end(), a[i].first) 
            - pos.begin() + m] = Convex(a[i].second);
        }
        for (u32 i = m - 1; i > 0; i--) {
            t[i] = Convex(t[i * 2].cv, t[i * 2 + 1].cv);
        }
    }

    u64 ask(u32 l, u32 r, u32 x) 
    {
        l = lower_bound(pos.begin(), pos.end(), l) - pos.begin();
        r = lower_bound(pos.begin(), pos.end(), r) - pos.begin();
        
        u64 res = 0;
        for (l += m, r += m; l < r; l /= 2, r /= 2) {
            if (l & 1) res = max(res, t[l++].ask(x));
            if (r & 1) res = max(res, t[--r].ask(x));
        }
        return res;
    }

private:

    u32 m;
    vector<u32> pos;
    vector<Convex> t;

};


class ChronoSegmentTree
{

public:

    ChronoSegmentTree(u32 _n): n(_n), m(1)
    {
        while (m < n) m += m;
        t.resize(m * 2);
        q.resize(m * 2);
    }

    void push_line(u32 l, u32 r, pair<u32, Line> op)
    {
        for (l += m, r += m; l < r; l /= 2, r /= 2) {
            if (l & 1) t[l++].emplace_back(op);
            if (r & 1) t[--r].emplace_back(op);
        }
    }

    void push_query(u32 x, qrt qr) { q[x + m].emplace_back(qr); }

    void solve()
    {
        for (u32 i = 0; i < n; i++) if (q[i + m].size()) {
            auto [x, l, r, tg] = q[i + m][0];
            ConvexSegmentTree sgt(t[i + m]);
            *tg = sgt.ask(l, r, x);
        }
        for (u32 i = m - 1; i > 0; i--) {
            q[i].resize(q[i * 2].size() + q[i * 2 + 1].size());
            merge(q[i * 2].begin(), q[i * 2].end(), 
            q[i * 2 + 1].begin(), q[i * 2 + 1].end(), q[i].begin(), 
            [](const qrt& a, const qrt& b){ return get<0>(a) < get<0>(b); });

            ConvexSegmentTree sgt(t[i]);
            for (auto [x, l, r, tg]: q[i]) *tg = max(*tg, sgt.ask(l, r, x));
        }
    }

private:

    u32 n, m;
    vector<vector<pair<u32, Line>>> t;
    vector<vector<qrt>> q;
};

signed main() 
{
    ios::sync_with_stdio(false); 
    cin.tie(0), cout.tie(0);
    u32 n, q;
    cin >> n >> q;
    vector<Line> l(n);
    vector<u32> st(n);
    for (auto &[a, b]: l) cin >> a >> b;

    vector<u64> ans(q + 1);
    ChronoSegmentTree csgt(q + 1);
    for (u32 i = 1, o, a, b, c; i <= q; i++) {
        cin >> o >> a >> b >> c;
        if (o == 1) {
            --a;
            csgt.push_line(st[a], i, {a, l[a]});
            st[a] = i, l[a] = Line(b, c);
        }
        else {
            csgt.push_query(i, qrt(a, b - 1, c, &ans[i]));
        }
    }
    for (u32 i = 0; i < n; i++) csgt.push_line(st[i], q + 1, {i, l[i]});
    csgt.solve();

    for (u32 i = 1; i <= q; i++) if (ans[i]) cout << ans[i] << '\n';
    return 0;
}