题目链接:https://codeforces.com/contest/1321/problem/E
题目大意:
有n个武器。每个有属性攻击力:a[i],价格:ca[i]。
有m个盾牌。每个有属性防御力:b[i],价格:bc[i]。
有k个怪物。每个有防御力xk, 攻击力yk,价值zk。
现在你必须并且只能买一个武器和一个盾牌。如果你的攻击力>怪物的防御力并且你的防御力>怪物的攻击力。那么你就可以打败这只怪物并且得到这只怪物价值的钱。所以你的收益为所有击败怪物的价值和-购买武器和盾牌的钱。现在让你最大化收益。
思路:我们枚举武器攻击力a[i]。那么我们可以打败的怪物只可能是x[i]<a[i]。我们我们把以盾牌的防御力y[i]为轴建立线段树。我们先把所有盾牌加入线段树。值为(-价格)。
那么我们在枚举a[i]时把所有x[i]<a[i]的怪物加入线段树。(b[i], k)。那么线段树就可以logn查询到现在的买当前武器,买任意盾牌可以收益的最大值。
线段树维护:sum为怪物得到价格前缀和,mx为买当前区间盾牌可能收益的最大值。分别维护就可以了
#include<bits/stdc++.h>
#define LL long long
#define mid (l+r)/2
using namespace std;
struct ode{
int x, y;
}a[200005];
struct gw{
int x, y, z;
}c[200005];
struct Node{
LL l, r;
LL sum, mx, pos;
}node[5000000];
void BT(LL i, LL l, LL r){
node[i].l=l;
node[i].r=r;
if(l==r){
node[i].mx=node[i].sum=node[i].pos=0;
return ;
}
BT(i<<1, l, mid);
BT((i<<1)+1, mid+1, r);
}
void GX(LL i, LL x, LL y, LL z){
if(node[i].l==node[i].r){
if(z==0){
node[i].sum+=y;
}
else{
if(node[i].pos==0){
node[i].mx=y;
node[i].pos=1;
}
else{
node[i].mx=max(node[i].mx, y);
node[i].pos=1;
}
}
return ;
}
if(x<=(node[i].l+node[i].r)/2){
GX(i<<1, x, y, z);
}
else{
GX((i<<1)+1, x, y, z);
}
if(node[i<<1].pos&&node[(i<<1)+1].pos){
node[i].mx=max(node[i<<1].mx, node[(i<<1)+1].mx+node[i<<1].sum);
node[i].pos=1;
}
else if(node[i<<1].pos){
node[i].mx=node[i<<1].mx;
node[i].pos=1;
}
else if(node[(i<<1)+1].pos){
node[i].mx=node[(i<<1)+1].mx+node[i<<1].sum;
node[i].pos=1;
}
node[i].sum=node[i<<1].sum+node[(i<<1)+1].sum;
}
LL CX(){
return node[1].mx;
}
int cmp(ode a, ode b){
return a.x<b.x;
}
int main(){
int n, m, k, x, y, z, tot=1;
scanf("%d%d%d",&n, &m, &k);
for(int i=1; i<=n; i++){
scanf("%d%d", &a[i].x, &a[i].y);
}
sort(a+1, a+1+n, cmp);
BT(1, 1, 1e6);
for(int i=1; i<=m; i++){
scanf("%d%d", &x, &y);
GX(1, x, -y, 1);
}
for(int i=1; i<=k; i++){
scanf("%d%d%d", &c[i].x, &c[i].y, &c[i].z);
}
LL mx=-(1ll<<60);
sort(c+1, c+k+1, [](gw &a, gw &b){return a.x<b.x;});
for(int i=1; i<=n; i++){
while(tot<=k&&c[tot].x<a[i].x){
GX(1, c[tot].y, c[tot].z, 0);
tot++;
}
LL ans=CX();
mx=max(mx, ans-a[i].y);
}
printf("%lld\n", mx);
return 0;
}