Submission #1189775

#TimeUsernameProblemLanguageResultExecution timeMemory
1189775onbertTwo Dishes (JOI19_dishes)C++20
82 / 100
10082 ms253044 KiB
#include <bits/stdc++.h>
using namespace std;
#define int long long
struct node {
    int mn, mx;
    bool sorted;
};
struct thing {
    int asgn, del;
};

void pass(thing &a, thing b) {
    if (b.asgn != -1) a = b;
    else if (a.asgn != -1) a.asgn += b.del;
    else a.del += b.del;
}
node merge(node a, node b) {
    node cur;
    cur.mn = min(a.mn, b.mn);
    cur.mx = max(a.mx, b.mx);
    cur.sorted = (a.sorted && b.sorted && (a.mx <= b.mn));
    return cur;
}
const int maxn = 1e6 + 5, maxN = 4e6 + 5, INF = 1e16;
int n, m;
int a[maxn], S[maxn], P[maxn];
int b[maxn], T[maxn], Q[maxn];
vector<pair<int, int>> pre[maxn], suf[maxn];

node seg[maxN];
thing lazy[maxN];
void build(int id, int l, int r) {
    seg[id] = {0, 0, 1}; lazy[id] = {-1, 0};
    if (l == r) return;
    int mid = (l+r)/2;
    build(id*2, l, mid); build(id*2+1, mid+1, r);
}
void push(int id) {
    if (lazy[id].asgn != -1) seg[id].mn = seg[id].mx = lazy[id].asgn;
    else seg[id].mn += lazy[id].del, seg[id].mx += lazy[id].del;
    if (id*2 < maxN) pass(lazy[id*2], lazy[id]);
    if (id*2+1 < maxN) pass(lazy[id*2+1], lazy[id]);
    lazy[id] = {-1, 0};
}
void update(int id, int l, int r, int findl, int findr, int val, int type) {
    push(id);
    if (r < findl || findr < l) return;
    if (findl <= l && r <= findr) {
        // cout << l << " " << r << " " << val << " " << type << endl;
        thing cur;
        if (type == 1) cur = {val, 0};
        else if (type == 2) cur = {-1, val};
        pass(lazy[id], cur);
        push(id);
        return;
    }
    int mid = (l+r)/2;
    update(id*2, l, mid, findl, findr, val, type);
    update(id*2+1, mid+1, r, findl, findr, val, type);
    seg[id] = merge(seg[id*2], seg[id*2+1]);
}
node qry(int id, int l, int r, int findl, int findr) {
    push(id);
    if (r < findl || findr < l) return {INF, -INF, 1};
    if (findl <= l && r <= findr) return seg[id];
    int mid = (l+r)/2;
    return merge(qry(id*2, l, mid, findl, findr), qry(id*2+1, mid+1, r, findl, findr));
}


signed main() {
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m;
    for (int i=1;i<=n;i++) cin >> a[i] >> S[i] >> P[i];
    for (int i=1;i<=m;i++) cin >> b[i] >> T[i] >> Q[i];
    a[0] = b[0] = 0;
    for (int i=1;i<=n;i++) a[i] += a[i-1];
    for (int i=1;i<=m;i++) b[i] += b[i-1];
    a[n+1] = INF, b[m+1] = INF;
    for (int i=1;i<=n;i++) {
        int val = upper_bound(b, b+m+1, S[i] - a[i]) - b - 1;
        // cout << S[i] - a[i] << endl;
        if (val != -1) suf[val].push_back({i, P[i]});
        // cout << i << " " << val << endl;
    }
    for (int i=1;i<=m;i++) {
        int val = upper_bound(a, a+n+1, T[i] - b[i]) - a - 1;
        if (val != -1) pre[i].push_back({val, Q[i]});
        // cout << i << " " << val << endl;
    }
    build(1, 0, n);
    // for (int i=1;i<=n;i++) cout << qry(1, 0, n, i, i).mx << endl;
    for (int i=0;i<=m;i++) {
        for (auto [pos, val]:pre[i]) {
            update(1, 0, n, 0, pos, val, 2);
            // for (int j=0;j<=pos;j++) dp[j] += val;
        }
        // for (int j=0;j<=n;j++) cout << qry(1, 0, n, j, j).mn << " "; cout << endl;
        // cout << qry(1, 0, n, 0, 1).sorted << endl;
        // return 0;
        while (!seg[1].sorted) {
            int l = 0, r = n;
            while (l < r) {
                int mid = (l+r+1)/2;
                if (qry(1, 0, n, 0, mid).sorted) l = mid;
                else r = mid-1;
            }
            int pos = l, val = qry(1, 0, n, 0, pos).mx;
            // cout << "test " << pos << " " << val << endl;
            l = pos+1, r = n;
            while (l < r) {
                int mid = (l+r+1)/2;
                if (qry(1, 0, n, pos+1, mid).mx < val) l = mid;
                else r = mid-1;
            }
            int lim = l;
            // cout << i << " " << pos << " " << lim << endl;
            update(1, 0, n, pos+1, lim, val, 1);
        }
        // for (int j=1;j<=n;j++) dp[j] = max(dp[j-1], dp[j]);
        for (auto [pos, val]:suf[i]) {
            update(1, 0, n, pos, n, val, 2);
            // for (int j=pos;j<=n;j++) dp[j] += val;
            // cout << "suf " << pos << " " << val << endl;
        }
    }
    cout << qry(1, 0, n, n, n).mx << "\n";
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...