CF1321E World of Darkraft: Battle for Azathoth

Title

Sort all attack equipment by attack value, all defense equipment by defense value, and all monsters by defense value

Then consider each piece of attack equipment i at once:

Since the attack equipment and the monster are sorted by attack value and defense value respectively, the range 1 of the monster subscript that meets the first condition (the attack value of the attack equipment is greater than the defense value of the monster)-j must increase monotonously (j monotonically increasing)

For all options of attacking equipment i, whether 1-j's monster can be defeated depends only on the defense value of the selected defense equipment k

Establish a line segment tree for the defense equipment. The line tree node stores the maximum benefit of the defense equipment in the selected interval. The initial value is the opposite of the price of each piece of defense equipment.

Update the line tree with 1-j monster: find the smallest k that can meet the second condition (defense value is greater than the monster attack value), then the kth-m pieces of equipment can meet the requirements, plus the monster ’s interval value

Then update the answer with the value of the root node of the line segment tree (1-the maximum value of m)-the price of the i-th attack equipment

Summary: The advantage of ordering the three sequences is that the range is monotonously rising (that is, only need to be modified once for each j), and the range of each modification is a period (available line tree maintenance)

#include <bits/stdc++.h>
using namespace std;
#define int long long
inline void read (int &x) {
    char ch = getchar(); x = 0;
    while (!isdigit(ch)) ch = getchar();
    while (isdigit(ch)) x = x * 10 + ch - 48, ch = getchar();
} const int N = 2e5 + 5;
int n, m, p, res = -1e12, c[N << 2], tag[N << 2], q[N];
pair<int, int> a[N], b[N];
pair<int, pair<int, int> > t[N];
#define fi first
#define se second
#define ls (p << 1)
#define rs (p << 1 | 1)
#define Max(a, b) (a < b ? b : a)
void build (int p, int l, int r) {
    if (l == r) { c[p] = -b[l].se; return; } int mid (l + r >> 1);
    build (ls, l, mid), build (rs, mid + 1, r), c[p] = Max (c[ls], c[rs]);
}
inline void push_down (int p) {
    tag[ls] += tag[p], tag[rs] +=tag[p];
    c[ls] += tag[p], c[rs] +=tag[p], tag[p] = 0;
}
void modify (int p, int l, int r, int ql, int qr, int val) {
    if (ql <= l && qr >= r) { c[p] += val, tag[p] += val; return; }
    int mid (l + r >> 1); push_down (p);
    if (ql <= mid) modify (ls, l, mid, ql, qr, val);
    if (qr > mid) modify (rs, mid + 1, r, ql, qr, val);
    c[p] = Max (c[ls], c[rs]);
}
inline void update (int p) {
    int tmp = upper_bound (q + 1, q + m + 1, t[p].se.fi) - q;
//    printf ("%d %d %d\n", p, t[p].se.fi, tmp);
    if (tmp <= m) modify (1, 1, m, tmp, m, t[p].se.se);
}
signed main() {
    read (n), read (m), read (p); int j = 1;
    for (int i = 1; i <= n; ++i) read (a[i].fi), read (a[i].se);
    for (int i = 1; i <= m; ++i) read (b[i].fi), read (b[i].se);
    for (int i = 1; i <= p; ++i) read (t[i].fi), read (t[i].se.fi), read (t[i].se.se);
    sort (a + 1, a + n + 1), sort (b + 1, b + m + 1), sort (t + 1, t + p + 1);
    for (int i = 1; i <= m; ++i) q[i] = b[i].fi; build (1, 1, m);
    for (int i = 1; i <= n; ++i) {
        while (j <= p && t[j].fi < a[i].fi) update (j++);
    //    printf ("%d %d\n", j, c[1]);
        res = Max (res, c[1] - a[i].se);
    } return printf ("%lld\n", res), 0;
}

Guess you like

Origin www.cnblogs.com/whx666/p/12674934.html