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;
    }
  • 相关阅读:
    算法_二叉查找树
    Java编程思想学习笔记_2(继承和多态)
    算法_符号表
    算法_优先队列
    算法_快速排序
    Java编程思想学习笔记_1(Java内存和垃圾回收)
    map 与 lambda 的用法
    优化版九九乘法表
    low版九九乘法表
    python3爬虫lxml模块的安装
  • 原文地址:https://www.cnblogs.com/ChrisKKK/p/11493679.html
Copyright © 2011-2022 走看看