World of Darkraft: Battle for Azathoth

Roma is playing a new expansion for his favorite game World of Darkraft. He made a new character and is going for his first grind.

Roma has a choice to buy exactly one of n different weapons and exactly one of m different armor sets. Weapon i has attack modifier ai and is worth cai coins, and armor set j has defense modifier bj and is worth cbj coins.

After choosing his equipment Roma can proceed to defeat some monsters. There are p monsters he can try to defeat. Monster k has defense xk, attack yk and possesses zk coins. Roma can defeat a monster if his weapon’s attack modifier is larger than the monster’s defense, and his armor set’s defense modifier is larger than the monster’s attack. That is, a monster k can be defeated with a weapon i and an armor set j if ai>xk and bj>yk. After defeating the monster, Roma takes all the coins from them. During the grind, Roma can defeat as many monsters as he likes. Monsters do not respawn, thus each monster can be defeated at most one.

Thanks to Roma’s excessive donations, we can assume that he has an infinite amount of in-game currency and can afford any of the weapons and armor sets. Still, he wants to maximize the profit of the grind. The profit is defined as the total coins obtained from all defeated monsters minus the cost of his equipment. Note that Roma must purchase a weapon and an armor set even if he can not cover their cost with obtained coins.

Help Roma find the maximum profit of the grind.

Input
The first line contains three integers n, m, and p (1≤n,m,p≤2⋅105) — the number of available weapons, armor sets and monsters respectively.

The following n lines describe available weapons. The i-th of these lines contains two integers ai and cai (1≤ai≤106, 1≤cai≤109) — the attack modifier and the cost of the weapon i.

The following m lines describe available armor sets. The j-th of these lines contains two integers bj and cbj (1≤bj≤106, 1≤cbj≤109) — the defense modifier and the cost of the armor set j.

The following p lines describe monsters. The k-th of these lines contains three integers xk,yk,zk (1≤xk,yk≤106, 1≤zk≤103) — defense, attack and the number of coins of the monster k.

Output
Print a single integer — the maximum profit of the grind.

Example

扫描二维码关注公众号,回复: 10584657 查看本文章
input
2 3 3
2 3
4 7
2 4
3 2
5 11
1 2 4
2 1 6
3 4 6
output
1

将武器和盔甲的效应值由小到大排序。
建造一个线段树,维护对于选择任意武器时打怪获得的钱减去购买武器的钱中的最大值。然后遍历每件盔甲,每遍历一件盔甲,由于防御值增加,仅考虑盔甲的话可以打得怪会增加,于是对于每个新增的怪,将线段树维护的区间中攻击值大于怪兽的防御值的武器统统加上该怪兽的钱数,最后用区间中的最值减去购买盔甲的花费的值来更新ans。

#include<bits/stdc++.h>


#define ll long long
using namespace std;
const int N = 2e5 + 10;
unordered_map<int, int> ca, cb;

struct P {
    int x, y, z;

    inline bool operator<(const P &w) const {
        return y < w.y;
    }
} mon[N];

int a[N], b[N], ta, tb, tmon;
struct T {
    int l, r;
    ll dat, add;
#define l(x) t[x].l
#define r(x) t[x].r
#define dat(x) t[x].dat
#define add(x) t[x].add
} t[N * 4];
int n, m, k;

inline void read() {
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 1; i <= n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        if (!ca[x])a[++ta] = x, ca[x] = y;
        else if (ca[x] > y)ca[x] = y;
    }
    sort(a + 1, a + ta + 1);
    for (int i = 1; i <= m; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        if (!cb[x])b[++tb] = x, cb[x] = y;
        else if (cb[x] > y)cb[x] = y;
    }
    sort(b + 1, b + tb + 1);
    for (int i = 1; i <= k; i++) {
        int x, y, z;
        scanf("%d%d%d", &x, &y, &z);
        if (x >= a[ta] || y >= b[tb])continue;
        x = upper_bound(a + 1, a + ta + 1, x) - a;
        mon[++tmon] = {x, y, z};
    }
    sort(mon + 1, mon + tmon + 1);
}

void build(int p, int l, int r) {
    l(p) = l, r(p) = r;
    if (l == r) {
        dat(p) = -ca[a[l]];
        return;
    }
    int mid = (l + r) >> 1;
    build(p << 1, l, mid);
    build(p << 1 | 1, mid + 1, r);
    dat(p) = max(dat(p << 1), dat(p << 1 | 1));
}

void spread(int p) {
    if (add(p)) {
        dat(p << 1) += add(p);
        dat(p << 1 | 1) += add(p);
        add(p << 1) += add(p);
        add(p << 1 | 1) += add(p);
        add(p) = 0;
    }
}

void change(int p, int l, int r, int d) {
    if (l <= l(p) && r >= r(p)) {
        dat(p) += d, add(p) += d;
        return;
    }
    spread(p);
    int mid = (l(p) + r(p)) >> 1;
    if (l <= mid)change(p << 1, l, r, d);
    if (r > mid)change(p << 1 | 1, l, r, d);
    dat(p) = max(dat(p << 1), dat(p << 1 | 1));
}

int main() {
    read();
    build(1, 1, ta);
    int now = 1;
    ll ans = -1e18;
    for (int i = 1; i <= tb; i++) {
        while (now <= tmon && mon[now].y < b[i])
            change(1, mon[now].x, ta, mon[now].z), now++;
        ans = max(ans, t[1].dat - cb[b[i]]);
    }
    printf("%lld\n", ans);
    return 0;
}
发布了360 篇原创文章 · 获赞 28 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_45323960/article/details/105202597
今日推荐