World of Darkraft: Battle for Azathoth CodeForces - 1321E(线段树+思维)

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
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
题意:
n件武器,杀伤力为ai,价格为cai。
m件盔甲,防御力为bi,价格为cbi。
p个怪物,防御力为xi,杀伤力为yi,价格为cpi。
挑选一件武器,一件盔甲,去杀怪物,问最大的收益是多少?
思路:我们将武器按照杀伤力由大到小排序,怪物按照防御力由大到小排序。盔甲按照防御力由大到小排序。我们遍历武器杀伤力,寻找它能打败的怪物。那么按照这个怪物的攻击力我们是可以在盔甲中找到一个范围的,这样武器和盔甲都符合杀死怪物的要求。我们按照盔甲排序后的顺序建立线段树,线段树上维护的是当前价值的最大值,起始值我们把盔甲的价格更新进去。后面的武器一定可以杀死符合之前武器的怪物,因此我们不需要从头遍历,节省时间。
代码如下:

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxx=2e5+100;
const int maxn=1e6+100;
struct Node{
	int x;
	ll c;
	bool operator <(const Node &z)const{
		return x<z.x;
	}
}a[maxx],b[maxx];
struct Node1{
	int x,y;
	ll c;
	bool operator<(const Node1 &z)const{
		return x<z.x;
	}
}c[maxx];
struct node{
	int l;
	int r;
	ll sum;
	ll lazy;
}p[maxx<<2];
int d[maxx];
int n,m,pp;
/*--------线段树--------*/
inline void pushup(int cur)
{
	p[cur].sum=max(p[cur<<1].sum,p[cur<<1|1].sum);
}
inline void pushdown(int cur)
{
	if(p[cur].lazy)
	{
		p[cur<<1].lazy+=p[cur].lazy;
		p[cur<<1|1].lazy+=p[cur].lazy;
		p[cur<<1].sum+=p[cur].lazy;
		p[cur<<1|1].sum+=p[cur].lazy;
		p[cur].lazy=0;
	}
}
inline void build(int l,int r,int cur)
{
	p[cur].l=l;
	p[cur].r=r;
	p[cur].lazy=0;
	if(l==r)
	{
		p[cur].sum=-b[l].c;
		return ;
	}
	int mid=l+r>>1;
	build(l,mid,cur<<1);
	build(mid+1,r,cur<<1|1);
	pushup(cur);
}
inline void update(ll v,int l,int r,int cur)
{
	int L=p[cur].l;
	int R=p[cur].r;
	if(l<=L&&R<=r)
	{
		p[cur].sum+=v;
		p[cur].lazy+=v;
		return ;
	}
	pushdown(cur);
	int mid=L+R>>1;
	if(r<=mid) update(v,l,r,cur<<1);
	else if(mid<l) update(v,l,r,cur<<1|1);
	else 
	{
		update(v,l,mid,cur<<1);
		update(v,mid+1,r,cur<<1|1);
	}
	pushup(cur);
}
int main()
{
	scanf("%d%d%d",&n,&m,&pp);
	for(int i=1;i<=n;i++) scanf("%d%lld",&a[i].x,&a[i].c);
	for(int i=1;i<=m;i++) scanf("%d%lld",&b[i].x,&b[i].c);
	for(int i=1;i<=pp;i++) scanf("%d%d%lld",&c[i].x,&c[i].y,&c[i].c);
	sort(a+1,a+1+n);//我方按照攻击力排序 
	sort(b+1,b+1+m);//我方按照防御力排序 
	sort(c+1,c+1+pp);//怪兽按着防御力排序
	for(int i=1;i<=m;i++) d[i]=b[i].x;
	build(1,m,1);
	int k=1;
	ll ans=-2e9;
	for(int i=1;i<=n;i++)
	{
		while(k<=pp&&a[i].x>c[k].x)
		{
			int pos=upper_bound(d+1,d+1+m,c[k].y)-d;
			if(pos<=m) update(c[k].c,pos,m,1);
			k++;
		}
		ans=max(ans,p[1].sum-a[i].c);
	}
	printf("%lld\n",ans);
	return 0;
}

努力加油a啊,(o)/~

发布了502 篇原创文章 · 获赞 26 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/starlet_kiss/article/details/104649015
今日推荐