Codeforces Round #625 Div1 C,二维偏序,排序+线段树


题目

题意:

有若干武器A,攻击力A1,费用A2,
有若干铠甲B,防御力B1,费用B2,
有若干怪兽M,攻击力M1,防御力M2,奖励M3
你可以选择一把武器,一个铠甲,打败所有攻击和防御都严格小的怪兽,问最大收益。

思路:

典型的二维偏序问题,把攻击和防御想象成二维的坐标轴,我们要找到的其实就是一个矩形里(0,0)~(x,y)里收益-这个矩形的花费的最大值。我们可以排序一维,另一维用线段树维护,枚举的时候往里面加怪兽就好。

代码:

#include 
using namespace std;
#define X first
#define Y second
#define PB push_back
#define LL long long
#define pii pair
#define MEM(x,y) memset(x,y,sizeof(x))
#define bug(x) cout<<"debug "#x" is "< MO[maxn];
void push_down(int p){
	lazy[lson(p)]+=lazy[p];
	lazy[rson(p)]+=lazy[p];
	lazy[p]=0;
}
void modify(int tr,int l,int r,int L,int R,int v){
	if(rR)return;
	if(L<=l&&r<=R){
        lazy[tr]+=v;
		return;
	}
	push_down(tr);
	int mid=(l+r)/2;
	modify(rson(tr),mid+1,r,L,R,v);
	modify(lson(tr),l,mid,L,R,v);
	sum[tr]=max(sum[lson(tr)]+lazy[lson(tr)],sum[rson(tr)]+lazy[rson(tr)]);
	return ;
}
int main(){
    FIO;
    LL ans= -inf;
	cin>>n>>m>>P;
	for(int i=1;i<=n;i++) cin>>A[i].X>>A[i].Y;
	for(int i=1;i<=m;i++) cin>>B[i].X >>B[i].Y;
	for(int i=1;i<=P;i++) cin>>MO[i].X >>MO[i].Y.X >>MO[i].Y.Y;
	sort(MO+1,MO+P+1);
	sort(A+1,A+n+1);
	sort(B+1,B+m+1);
	MEM(lazy,0);MEM(sum,0);
	N = m;
    for(int i=1;i<=m;i++) modify(1,1,N,i,i,-B[i].Y);
	for(int idx=1,i=1;i<=n;i++){
		while(MO[idx].X