poj2482 Stars in Your Window[扫描线]

平面内若干带权点,有一个固定矩形,求框住的点最大权值和。


连这种题都不会了我真的没救了。

每个点会对框住他的矩形产生一个贡献,为了方便表示可以用一个点表示以这个点为右上角的矩形。于是每个店都有一个对应区域,在这个区域内的矩形顶点都有贡献。然后就是在若干矩形中找权值最大点了。看到很多重叠矩形就可以想到这个就是扫描线了,离散化关键点之后维护max即可。

可以看出,这题的瓶颈还在于转化


一些提醒:

多测不清空,爆零两行泪。

仔细研读数据范围。本题坐标超出$2^{31}-1$一点点。用ll。


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define dbg(x) cerr<<#x<<" = "<<x<<endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
template<typename T>inline char MIN(T&A,T B){return A>B?A=B,1:0;}
template<typename T>inline char MAX(T&A,T B){return A<B?A=B,1:0;}
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline T read(T&x){
    x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
    while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
}
const int N=1e4+7,INF=0x3f3f3f3f;
struct edge{
    ll l,r,y;int c;
    edge(ll l=0,ll r=0,ll y=0,int c=0):l(l),r(r),y(y),c(c){}
    inline bool operator <(const edge&thxorz)const{return y<thxorz.y;}
}A[N<<1];
ll X[N<<1];
int n,w,h,m,x,y,c,ans;
#define lc i<<1
#define rc i<<1|1
int maxv[N<<4],tag[N<<4];
inline void Pushup(int i){maxv[i]=_max(maxv[lc],maxv[rc]);}
inline void Pushdown(int i){if(tag[i])tag[lc]+=tag[i],tag[rc]+=tag[i],maxv[lc]+=tag[i],maxv[rc]+=tag[i],tag[i]=0;}
void Update_add(int i,int L,int R,int ql,int qr,int val){
    if(ql<=L&&qr>=R){tag[i]+=val,maxv[i]+=val;return;}
    Pushdown(i);int mid=L+R>>1;
    if(ql<=mid)Update_add(lc,L,mid,ql,qr,val);
    if(qr>mid)Update_add(rc,mid+1,R,ql,qr,val);
    Pushup(i);
}

int main(){//freopen("test.in","r",stdin);freopen("test.out","w",stdout);
    while(~scanf("%d%d%d",&n,&w,&h)){
        memset(maxv,0,sizeof maxv),memset(tag,0,sizeof tag),ans=0;
        for(register int i=1,t=0;i<=n;++i)read(x),read(y),read(c),A[++t]=edge(x,x+0ll+w-1,y,c),X[t]=x,A[++t]=edge(x,x+0ll+w-1,y+0ll+h,-c),X[t]=x+0ll+w-1;
        sort(X+1,X+2*n+1);m=unique(X+1,X+2*n+1)-X-1;
        sort(A+1,A+2*n+1);A[2*n+1].y=-1;
        for(register int i=1;i<=2*n;++i){
            x=lower_bound(X+1,X+m+1,A[i].l)-X,y=lower_bound(X+1,X+m+1,A[i].r)-X,Update_add(1,1,m,x,y,A[i].c);
            if(A[i].y^A[i+1].y)MAX(ans,maxv[1]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2019-08-25 21:17  Ametsuji_akiya  阅读(119)  评论(0编辑  收藏  举报