codeforces 625 E. World of Darkraft: Battle for Azathoth

The meaning of problems

Purchase weapons and equipment, attack and defense are greater than a monster when you can get his benefits.
Seeking total return (to remove the money to buy weapons and equipment) maximum

answer

First the best weapons and equipment prices must be increased with the increase of the property.
It can be used to obtain the minimum suffix, of course, I use the monotonous queue.
After obtaining the price, we consider the sort of monsters attack.
Traversal, each get their big weapons attack power of the minimum price, then traversed the need to find all I could get maximum benefit.
Consider segment tree.
Total defense Only 1 e 6 1e6 , we deal with the pre-purchase each point to reach this point is greater than the value of defense equipment minimum price, minus the price at that point, and then each time adding a new monster, because the back of the defense has value contribution, so the actual update interval [ d e f e n c e , l e n ] [Defense only] . (Do not take + 1 +1 reason is that when we deal with are larger than the point. )
And then take the global optimum value.
Note that only buy special equipment sentence.

#include<bits/stdc++.h>
#define FOR(i,l,r) for(int i=l;i<=r;i++)
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;

const int maxn=1e6+500000;

struct tree2{
    tree2 *lson,*rson;
    ll x,lazy;
}dizhi[maxn<<2],*root=&dizhi[0];

int n,m,p,t=1,len=1e6+500;
ll A[maxn];

void push_up(tree2 *tree,int l,int r){
    tree->x=max(tree->lson->x,tree->rson->x);
}

void push_down(tree2 *tree,int l,int r){
    if(!tree->lazy)return ;
    tree->lson->x+=tree->lazy;
    tree->rson->x+=tree->lazy;
    tree->lson->lazy+=tree->lazy;
    tree->rson->lazy+=tree->lazy;
    tree->lazy=0;
}

void build(tree2 *tree,int l,int r){
    if(l==r){
        tree->x=A[l];
        return ;
    }
    tree->lson=&dizhi[t++];
    tree->rson=&dizhi[t++];
    int mid=(l+r)>>1;
    build(tree->lson,l,mid);
    build(tree->rson,mid+1,r);
    push_up(tree,l,r);
}

void update(tree2 *tree,int l,int r,int x,int y,ll d){
    if(x<=l&&r<=y){
        tree->x+=d;
        tree->lazy+=d;
        return ;
    }
    push_down(tree,l,r);
    int mid=(l+r)>>1;
    if(x<=mid)update(tree->lson,l,mid,x,y,d);
    if(y>mid)update(tree->rson,mid+1,r,x,y,d);
    push_up(tree,l,r);
}

ll query(tree2 *tree,int l,int r,int x,int y){
    if(x<=l&&r<=y)return tree->x;
    push_down(tree,l,r);
    int mid=(l+r)>>1;
    ll t1=-inf,t2=-inf;
    if(x<=mid)t1=query(tree->lson,l,mid,x,y);
    if(y>mid)t2=query(tree->rson,mid+1,r,x,y);
    return max(t1,t2);
}

deque<pair<int,int> >dq;
vector<pair<int,int> >weapens;
vector<pair<int,int> >armor;
vector<pair<int,int> >G;
vector<pair<int,pair<int,int> > >monster;

int main(){
    cin>>n>>m>>p;
    G.clear();
    ll L=inf,R=inf;
    for(int i=1;i<=n;i++){
        int l,r;scanf("%d%d",&l,&r);
        G.push_back(make_pair(l,r));
        L=min(L,1ll*r);
    }
    sort(G.begin(),G.end());
    for(int i=0;i<G.size();i++){
        while(!dq.empty()&&G[i].second<=dq.back().second)dq.pop_back();
        dq.push_back(make_pair(G[i].first,G[i].second));
        //cout<<G[i].first<<" "<<G[i].second<<endl;
    }
    while(!dq.empty()){
        weapens.push_back(make_pair(dq.front().first,dq.front().second));
        dq.pop_front();
    }
    G.clear();
    for(int i=1;i<=m;i++){
        int l,r;scanf("%d%d",&l,&r);
        G.push_back(make_pair(l,r));
        R=min(R,1ll*r);
    }
    sort(G.begin(),G.end());
    for(int i=0;i<G.size();i++){
        while(!dq.empty()&&G[i].second<=dq.back().second)dq.pop_back();
        dq.push_back(make_pair(G[i].first,G[i].second));
    }
    while(!dq.empty()){
        armor.push_back(make_pair(dq.front().first,dq.front().second));
        dq.pop_front();
    }
    int pos,git;ll val;
    pos=-1,git=-1,val=-inf;
    for(int i=1;i<=len;i++){
        while(git<=i&&pos+1<armor.size()){
            pos++;
            git=armor[pos].first;
            val=armor[pos].second;
        }
        if(git>i)A[i]=-val;
        else A[i]=-inf;
    }
    build(root,1,len);
    for(int i=1;i<=p;i++){
        int l,r,mid;scanf("%d%d%d",&l,&r,&mid);
        monster.push_back(make_pair(l,make_pair(r,mid)));
    }
    sort(monster.begin(),monster.end());
    ll ans=-L-R,now=0;
    pos=-1,git=-1,val=-inf;
    for(int i=0;i<monster.size();i++){
        int attack=monster[i].first,defence=monster[i].second.first,profit=monster[i].second.second;
        while(git<=attack&&pos+1<weapens.size()){
            pos++;
            git=weapens[pos].first;
            val=weapens[pos].second;
        }
        update(root,1,len,defence,len,profit);
        if(git>attack){
            now=-val+root->x;
            ans=max(ans,now);
        }
    }
    cout<<ans<<endl;
}

Published 203 original articles · won praise 17 · views 20000 +

Guess you like

Origin blog.csdn.net/mxYlulu/article/details/104605258