• 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;
    }
  • 相关阅读:
    用感知机(Perceptron)实现逻辑AND功能的Python3代码
    xpadder教程:自定义设置游戏手柄的图片
    用Python实现小说中的汉字频率统计
    天猫精灵X1智能音箱使用感想
    一道常被人轻视的前端JS面试题
    jQueryNotes仿QQ空间添加标记
    JQ对象到底是什么
    正则匹配规则
    自定义右键菜单
    IIS处理并发请求时出现的问题及解决
  • 原文地址:https://www.cnblogs.com/ChrisKKK/p/11493679.html
Copyright © 2020-2023  润新知