zoukankan      html  css  js  c++  java
  • Luogu_1502 窗口的星星【题解】扫描线

    题目链接:https://www.luogu.org/problem/P1502

    其实一眼看不出扫描线。

    我们可以把每一个点都变成一个长宽为w和h的矩形。

    左边的边是+w,右边的边是-w。

    线段树维护区间max和lazy tag。

    然后扫描线求max。

    代码如下:

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=20010;
    int n,w,h,t,b[maxn<<1],tot;
    struct node{
        ll mx,tag;
        #define mx(x) tree[x].mx
        #define tag(x) tree[x].tag
    }tree[maxn<<2];
    struct s{
        int x,yl,yh,fl;
        s(){}
        s(int xx,int yy1,int yy2,int ff){x=xx;yl=yy1;yh=yy2;fl=ff;}
    }e[maxn<<1];
    inline bool cmp(s x,s y){
        return x.x==y.x ? x.fl>y.fl : x.x<y.x;
    }
    inline void pushdown(int p,int l,int r){
        if(!tag(p)) return;
        mx(p)+=tag(p);
        if(l!=r){
            tag(p<<1)+=tag(p);
            tag(p<<1|1)+=tag(p);
        }
        tag(p)=0;
    }
    inline void add(int p,int l,int r,int x,int y,int d){
        if(x<=l&&r<=y){
            tag(p)+=d;return;
        }
        int mid=(l+r)>>1;
        if(x<=mid) add(p<<1,l,mid,x,y,d);
        if(y>mid) add(p<<1|1,mid+1,r,x,y,d);
        pushdown(p<<1,l,mid);
        pushdown(p<<1|1,mid+1,r);
        mx(p)=max(mx(p<<1),mx(p<<1|1));
    }
    int main()
    {
        scanf("%d",&t);
        while(t--){
            memset(tree,0,sizeof(tree));
            tot=0;
            scanf("%d%d%d",&n,&w,&h);
            for(int i=1;i<=n;i++){
                int x,y,v;
                scanf("%d%d%d",&x,&y,&v);
                e[++tot].x=x;b[tot]=y;
                e[tot].yl=y;e[tot].yh=y+h-1;e[tot].fl=v;
                e[++tot].x=x+w-1;b[tot]=y+h-1;
                e[tot].yl=y;e[tot].yh=y+h-1;e[tot].fl=-v;
            }
            sort(b+1,b+1+2*n);
            tot=unique(b+1,b+1+2*n)-b-1;
            sort(e+1,e+1+2*n,cmp);
            ll ans=0;
            for(int i=1;i<=2*n;i++){
                int h1=lower_bound(b+1,b+1+tot,e[i].yh)-b;
                int h2=lower_bound(b+1,b+1+tot,e[i].yl)-b;
                e[i].yl=h2;e[i].yh=h1;
            }
            for(int i=1;i<=2*n;i++){
              add(1,1,2*n,e[i].yl,e[i].yh,e[i].fl);
              ans=max(ans,mx(1));
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    leetcode 268. Missing Number
    DBSCAN
    python二维数组初始化
    leetcode 661. Image Smoother
    leetcode 599. Minimum Index Sum of Two Lists
    Python中的sort() key含义
    leetcode 447. Number of Boomerangs
    leetcode 697. Degree of an Array
    滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(1月3日)
    北京Uber优步司机奖励政策(1月2日)
  • 原文地址:https://www.cnblogs.com/ChrisKKK/p/11493679.html
Copyright © 2011-2022 走看看