CodeForces 1321E. World of Darkraft: Battle for Azathoth(线段树)

Posted bakacirno

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces 1321E. World of Darkraft: Battle for Azathoth(线段树)相关的知识,希望对你有一定的参考价值。

传送门

题意

(a_1,a_2,...,a_n)(b_1,b_2,...,b_m)((x_1,y_1,w_1),(x_2,y_2,w_2),...,(x_p,y_p,w_p))

[max_{1le ile n,1le jle m}{sum_{x_k<a_i,y_k<b_j}w_k-a_i-b_j}]
其实就是分别选一个 (a_i,b_j),求矩形 ((0,0),(a_i,b_j)) 内部的点的 (w) 总和减 (a_i+b_j) 的最大值

题解

这种偏序问题基本上都可以考虑用线段树解决
借助扫描线的思维,枚举 x 轴枚举,线段树维护 y 轴
沿着 x 轴依次将点值加入其 y 轴对应坐标,然后直接查询线段树中的最大值
这个线段树显然应该维护前缀和,这样我们的到的最大值就是前缀和的最大值
就是问题的答案了
当然最初时要将 (b_j) 从线段树上减去

代码

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int,LL> PII;
const int inf=0x3f3f3f3f;
const LL INF=0x3f3f3f3f3f3f3f3f;
const int MAXN=2e5+10;
const int MAXM=1e6+10;
int n,m,p;
PII a[MAXN],b[MAXN],temp[MAXN];
struct Turp{
    int x,y,w;
}t[MAXN];
bool cmp(Turp a,Turp b){return a.x<b.x;}
struct SegTree{
    #define mid ((l+r)>>1)
    LL maxv[MAXM*4],tag[MAXM*4];
    void pushdown(int id){
        maxv[id<<1]+=tag[id];tag[id<<1]+=tag[id];
        maxv[id<<1|1]+=tag[id];tag[id<<1|1]+=tag[id];
        tag[id]=0;
    }
    void update(int id,int l,int r,int L,int R,LL x,int opt){
        if(L<=l&&r<=R)
            if(opt) {maxv[id]+=x;tag[id]+=x;return;}
            else {maxv[id]=max(maxv[id],x);return;}
        if(tag[id]) pushdown(id);
        if(L<=mid) update(id<<1,l,mid,L,R,x,opt);
        if(R>mid) update(id<<1|1,mid+1,r,L,R,x,opt);
        maxv[id]=max(maxv[id<<1],maxv[id<<1|1]);
    }
    #undef mid
}tr;

int main(){
    scanf("%d%d%d",&n,&m,&p);
    for(int i=1;i<=n;i++) scanf("%d%d",&a[i].first,&a[i].second);
    for(int i=1;i<=m;i++) scanf("%d%d",&b[i].first,&b[i].second);
    for(int i=1;i<=p;i++) scanf("%d%d%d",&t[i].x,&t[i].y,&t[i].w);
    sort(a+1,a+n+1);
    sort(b+1,b+m+1);
    sort(t+1,t+p+1,cmp);
    memset(tr.maxv,0xc0,sizeof(tr.maxv));
    LL temp=-INF;
    for(int i=1e6,j=m;i>=0;i--){
        while(i<b[j].first) temp=max(temp,-b[j].second),j--;
        tr.update(1,0,1e6,i,i,temp,0);
    }
    LL ans=-INF;
    for(int i=1,j=1;i<=n;i++){
        while(j<=p&&t[j].x<a[i].first) tr.update(1,0,1e6,t[j].y,1e6,t[j].w,1),j++;
        ans=max(ans,tr.maxv[1]-a[i].second);
    }
    cout<<ans<<endl;
    return 0;
}

以上是关于CodeForces 1321E. World of Darkraft: Battle for Azathoth(线段树)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #625 Div. 2 D E

Codeforces 1321D Navigation System

[Codeforces#519E] A and B and Lecture Rooms

Codeforces 1321D Navigation System

Codeforces - 1321B - Journey Planning(思维)

如何使用动态规划自顶向下方法解决这个 p‌r‌o‌b‌l‌e‌m?