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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章