zoukankan      html  css  js  c++  java
  • 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
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    C#用递归求阶乘 n!
    视图与表的区别和联系(小结)
    ref 和 out 的异同
    什么是重载?(最文艺的理解)
    [windows c]关于winsock2.h的recv函数的记录
    [windows c]关于指针函数和参数可变函数同时应用情况的疑问
    [windows c]CreateProcess
    c++ boost asio库初学习
    c#中ObservableCollection<T>排序方法
    安装opensuse时遇到的一些问题
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/11409409.html
Copyright © 2011-2022 走看看