CF1320C 【World of Darkraft: Battle for Azathoth】
必须买一个武器,买一个防具,然后去打怪,求最大收益。
由于武器的攻击力必须严格大于怪物的防御力,所以我们先满足每个武器的条件,然后去配一个最优收益的防具。
所以我们可以把武器案攻击力排序,怪物按防御力排序,然后枚举每一个武器时可以发现他们的大于区间是单调上升的。
既然如此,那我们不如枚举每一个怪物,然后动态更新每一款防具的收益,找到防具的最大收益即可。
但我们怎么更新每一款防具的收益呢?易知,怪物攻击力必须小于防具防御力,所以我们只需要更新那些防御力比怪物攻击力大的去更新,如果我们把防具按防御力大小排序,这就是一个区间修改问题,右端点已经确定,那我们怎么确定做端点呢?可以用二分查找第一个比它大的就行了。
下面是代码:
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 2e5 + 5;
int n , m , p , t[MAXN << 2] , tag[MAXN << 2];
struct node2 {
int x , y , z;
}mon[MAXN];
struct node {
int val , cost;
node () {}
node (int x) {
val = x;
}
bool operator < (const node x) const {
return val < x.val;
}
}a[MAXN] , b[MAXN];
bool cmp(node x , node y) {
if(x.val == y.val) return x.cost < y.cost;
return x.val < y.val;
}
bool cmp1(node2 x , node2 y) {
return x.x < y.x;
}
void push_down(int now) {
if(tag[now]) {
t[now << 1] += tag[now];
t[now << 1 | 1] += tag[now];
tag[now << 1] += tag[now];
tag[now << 1 | 1] += tag[now];
tag[now] = 0;
}
}
void build(int l , int r , int now) {
if(l == r) {
t[now] = -b[l].cost;
return;
}
int mid = (l + r) >> 1;
build(l , mid , now << 1);
build(mid + 1 , r , now << 1 | 1);
t[now] = max(t[now << 1] , t[now << 1 | 1]);
}
void update(int l , int r , int now , int x , int y , int z) {
if(x > y) return;
if(l >= x && r <= y) {
t[now] += z;
tag[now] += z;
return;
}
int mid = (l + r) >> 1;
push_down(now);
if(x <= mid) update(l , mid , now << 1 , x , y , z);
if(y > mid) update(mid + 1 , r , now << 1 | 1 , x , y , z);
t[now] = max(t[now << 1] , t[now << 1 | 1]);
}
int main() {
scanf("%d %d %d" , &n , &m , &p);
for (int i = 1; i <= n; ++i) scanf("%d %d" , &a[i].val , &a[i].cost);
sort(a + 1 , a + 1 + n , cmp);
for (int i = 1; i <= m; ++i) scanf("%d %d" , &b[i].val , &b[i].cost);
sort(b + 1 , b + 1 + m , cmp);
build(1 , m , 1);
for (int i = 1; i <= p; ++i) scanf("%d %d %d" , &mon[i].x , &mon[i].y , &mon[i].z);
sort(mon + 1 , mon + 1 + p , cmp1);
int l = 1 , ans = -2e9;
for (int i = 1; i <= p; ++i) {
if(mon[i].x < a[l].val) {
int x = upper_bound(b + 1 , b + 1 + m , node(mon[i].y)) - b;
update(1 , m , 1 , x , m , mon[i].z);
}
else {
ans = max(ans , t[1] - a[l].cost);
l ++;
if(l > n) break;
i --;
}
}
for (int i = l; i <= n; ++i) ans = max(ans , t[1] - a[i].cost);
printf("%d" , ans);
return 0;
}