Codeforces Round #625 (Div. 2, based on Technocup ...) E. World of Darkraft: Battle for(线段树)

题目链接

E. World of Darkraft: Battle for Azathoth

time limit per test

2 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

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 nn different weapons and exactly one of mm different armor sets. Weapon ii has attack modifier aiai and is worth caicai coins, and armor set jj has defense modifier bjbj and is worth cbjcbj coins.

After choosing his equipment Roma can proceed to defeat some monsters. There are pp monsters he can try to defeat. Monster kk has defense xkxk, attack ykyk and possesses zkzk 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 kk can be defeated with a weapon ii and an armor set jj if ai>xkai>xk and bj>ykbj>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 nn, mm, and pp (1≤n,m,p≤2⋅1051≤n,m,p≤2⋅105) — the number of available weapons, armor sets and monsters respectively.

The following nn lines describe available weapons. The ii-th of these lines contains two integers aiai and caicai (1≤ai≤1061≤ai≤106, 1≤cai≤1091≤cai≤109) — the attack modifier and the cost of the weapon ii.

The following mm lines describe available armor sets. The jj-th of these lines contains two integers bjbj and cbjcbj (1≤bj≤1061≤bj≤106, 1≤cbj≤1091≤cbj≤109) — the defense modifier and the cost of the armor set jj.

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

Output

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

Example

input

Copy

2 3 3
2 3
4 7
2 4
3 2
5 11
1 2 4
2 1 6
3 4 6

output

Copy

1

题意:给你n(n<=2e5)种武器,第i种武器拥有攻击力ai和价格bi。再给你m(m<=2e5)种盔甲,第i种盔甲拥有防御力xi和价格yi。再给你p(p<=2e5)只怪物,第i只怪物拥有攻击力ci,防御力di,价值ei。

其中ai,xi,ci,di<=1e6,ei<=1e3,bi,yi<=1e9。

现在你只能选择一种武器和一种盔甲,对于p只怪兽,如果你的攻击力严格大于这只怪兽的攻击力(a>ci)并且你的防御力严格大于这只怪兽的防御力(x>di),那么你就可以获得这只怪物的收益ei。

求最大的收益。

思路:二维偏序。按怪物的攻击力ci从小到大排序,然后用线段树维护防御力对应的最大的收益。(也就是说,叶子结点就是得到这个大小防御力的最大收益)。这样我们可以先预处理出攻击力/防御力为k时的最大收益。这样就可以依次枚举每只怪物i,从攻击力为[ci+1,maxn]中选一种最便宜的武器,再从[di+1,maxn]中选一个收益最大的盔甲即可(直接查询线段树)。

需要注意的是:

①要开long long,特别是上界inf要取long long的上界,线段树放结构体里面节省空间

②预处理的时候,注意防御力为maxn+1的盔甲价格得是inf。

代码:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f3f3f3f3fLL
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define dep(i,a,b) for(register int i=(a);i>=(b);i--)
#define ls (rt<<1)
#define rs (rt<<1|1)
using namespace std;
const int maxn=1e6+5;
//const double pi=acos(-1.0);
//const double eps=1e-9;
//const ll mo=1e9+7;
int n,m,nn,p;
ll ma[maxn+5],mb[maxn+5];
struct node
{
    int x,y,z;
    bool operator<(node aa)const
    {
        return x<aa.x||(x==aa.x&&y<aa.y);
    }
}a[maxn+5];
struct SegmentTree
{
    ll c[(maxn<<2)+5],lz[(maxn<<2)+5];
    void pu(int rt){c[rt]=max(c[ls],c[rs]);}
    void pd(int rt)
    {
        if(lz[rt])
        {
            lz[ls]+=lz[rt];
            lz[rs]+=lz[rt];
            c[ls]+=lz[rt];
            c[rs]+=lz[rt];
            lz[rt]=0;
        }
    }
    void build(int rt,int l,int r)
    {
        if(l==r) c[rt]=-mb[l];
        else
        {
            int mid=(l+r)>>1;
            build(ls,l,mid);
            build(rs,mid+1,r);
            pu(rt);
        }
        lz[rt]=0;
    }
    void update(int rt,int l,int r,int ql,int qr,ll v)
    {
        if(ql<=l&&r<=qr) {lz[rt]+=v;c[rt]+=v;return;}
        pd(rt);
        int mid=(l+r)>>1;
        if(ql<=mid) update(ls,l,mid,ql,qr,v);
        if(qr>mid) update(rs,mid+1,r,ql,qr,v);
        pu(rt);
    }
    ll query(int rt,int l,int r,int ql,int qr)
    {
        if(ql<=l&&r<=qr) return c[rt];
        pd(rt);
        int mid=(l+r)>>1;
        ll sum=-inf;
        if(ql<=mid) sum=query(ls,l,mid,ql,qr);
        if(qr>mid) sum=max(sum,query(rs,mid+1,r,ql,qr));
        return sum;
        pu(rt);
    }
}st;
int main()
{
    nn=maxn;
    scanf("%d%d%d",&n,&m,&p);
    rep(i,1,nn+1) ma[i]=mb[i]=inf;
    rep(i,1,n)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        ma[x]=min(ma[x],(ll)y);
    }
    rep(i,1,m)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        mb[x]=min(mb[x],(ll)y);
    }
    dep(i,nn,1)
    {
        ma[i]=min(ma[i],ma[i+1]);
        mb[i]=min(mb[i],mb[i+1]);
    }
    st.build(1,1,nn);
    rep(i,1,p) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    sort(a+1,a+1+p);

    ll ans=-ma[1]-mb[1];
    rep(i,1,p)
    {
        st.update(1,1,nn,a[i].y+1,nn,a[i].z);
        ll tmp=-ma[a[i].x+1]+st.query(1,1,nn,a[i].y+1,nn);
        //cout<<ans<<" "<<tmp<<endl;
        ans=max(ans,tmp);
    }
    printf("%lld\n",ans);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值