POJ 2482 Stars in Your Window

线段树+离散化+扫描线

AC之后,又认真读了一遍题目,好文章。

#include<cstdio>
#include<map>
#include<algorithm>
using namespace std;

const int maxn=100000+10;
int n;
long long W,H;
long long x[maxn],y[maxn],v[maxn];
struct seg
{
    long long X;
    long long Y1,Y2;
    long long val;
}s[2*maxn];
struct SegTree
{
    long long MAX;
    long long add;
}segTree[4*maxn];

map<long long,int>m;
long long M[maxn];
int k;

bool cmp(const seg&a,const seg&b)
{
    if(a.X==b.X) return a.val>b.val;
    return a.X<b.X;
}

void pushUp(int rt)
{
    segTree[rt].MAX=max(segTree[2*rt].MAX,segTree[2*rt+1].MAX);
}

void pushDown(int rt)
{
    if(segTree[rt].add)
    {
        segTree[2*rt].add+=segTree[rt].add;
        segTree[2*rt+1].add+=segTree[rt].add;
        segTree[2*rt].MAX+=segTree[rt].add;
        segTree[2*rt+1].MAX+=segTree[rt].add;
        segTree[rt].add=0;
    }
}

void build(int l,int r,int rt)
{
    segTree[rt].add=0;
    segTree[rt].MAX=0;
    if(l==r) return;

    int m=(l+r)/2;
    build(l,m,2*rt);
    build(m+1,r,2*rt+1);
}

void update(long long val,int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        segTree[rt].add+=val;
        segTree[rt].MAX+=val;
        return;
    }

    pushDown(rt);
    int m=(l+r)/2;
    if(L<=m) update(val,L,R,l,m,2*rt);
    if(R>m)  update(val,L,R,m+1,r,2*rt+1);
    pushUp(rt);
}

void lsh()
{
    m.clear();
    k=0;
    for(int i=1;i<=n;i++)
    {
        if(m[y[i]]==0)
        {
            m[y[i]]=1;
            M[k++]=y[i];
        }
        if(m[y[i]+H-1]==0)
        {
            m[y[i]+H-1]=1;
            M[k++]=y[i]+H-1;
        }
    }
    sort(M,M+k);
    //m.clear();   这个地方比较奇葩。清空了会TLE。。。。
    for(int i=0;i<k;i++) m[M[i]]=i+1;
}

int main()
{
    //freopen("F:\\in.txt","r",stdin);
    while(~scanf("%d%lld%lld",&n,&W,&H))
    {
        for(int i=1;i<=n;i++) scanf("%lld%lld%lld",&x[i],&y[i],&v[i]);
        lsh();
        int tot=0;
        for(int i=1;i<=n;i++)
        {
            s[tot].X=x[i];
            s[tot].Y1=m[y[i]];
            s[tot].Y2=m[y[i]+H-1];
            s[tot].val=v[i];
            tot++;

            s[tot].X=x[i]+W-1;
            s[tot].Y1=m[y[i]];
            s[tot].Y2=m[y[i]+H-1];
            s[tot].val=-v[i];
            tot++;
        }

        sort(s,s+tot,cmp);

        build(1,k,1);

        long long max_val=0;

        for(int i=0;i<tot;i++)
        {
            update(s[i].val,s[i].Y1,s[i].Y2,1,k,1);
            max_val=max(segTree[1].MAX,max_val);
        }
        printf("%lld\n",max_val);
    }
    return 0;
}
时间: 2024-09-29 02:23:48

POJ 2482 Stars in Your Window的相关文章

POJ 2482 Stars in Your Window 线段树+离散化+扫描线

题面据说很美- 每个星星可以根据在窗口的左下角和右上角两个位置建立两条扫描线,之后就是简单的区间增减和求最大值操作了. 注意要处理在边界上的星星是不算的情况,其实只要把左右边界分别增减一个eps即可. #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <

poj 2482 Stars in Your Window(扫描线)

题目链接:poj 2482 Stars in Your Window 题目大意:平面上有N个星星,问一个W?H的矩形最多能括进多少个星星. 解题思路:扫描线的变形.只要以每个点为左上角,建立矩形,这个矩形即为框框左下角放的位置可以括到该点,那么N个星星就有N个矩形,扫描线处理哪些位置覆盖次数最多. #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using

POJ 2482 Stars in Your Window(线段树)

POJ 2482 Stars in Your Window 题目链接 题意:给定一些星星,每个星星都有一个亮度,现在要用w * h的矩形去框星星,问最大能框的亮度是多少 思路:转化为扫描线的问题,每个星星转化为一个矩形,那么等于求矩形相交区域值最大的区域,利用线段树去维护即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long lo

POJ 2482 Stars in Your Window 线段树扫描线

Stars in Your Window Description Fleeting time does not blur my memory of you. Can it really be 4 years since I first saw you? I still remember, vividly, on the beautiful Zhuhai Campus, 4 years ago, from the moment I saw you smile, as you were walkin

(中等) POJ 2482 Stars in Your Window,静态二叉树。

Description Here comes the problem: Assume the sky is a flat plane. All the stars lie on it with a location (x, y). for each star, there is a grade ranging from 1 to 100, representing its brightness, where 100 is the brightest and 1 is the weakest. T

poj 2482 Stars in Your Window(线段树+扫描线+离散化)

Stars in Your Window Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10433   Accepted: 2874 Description Fleeting time does not blur my memory of you. Can it really be 4 years since I first saw you? I still remember, vividly, on the beaut

poj 2482 Stars in Your Window (线段树:区间更新)

题目链接:http://poj.org/problem?id=2482 读完题干不免有些心酸(??????) 题意:有n个星星(星星i的坐标为xi, yi,亮度为ci),给你一个W*H的矩形,让你求得矩形能覆盖的星星的亮度和最大为多少 思路:矩形大小是固定的,所以可以换个方向思考,把矩形看成一个点(坐标为矩形中心),每个星星的影响区间范围为W*H的矩形(星星原来的坐标为矩形中心),该区间的亮度增加c.该问题就变成了求哪个点的亮度最大.坐标范围太大,直接暴力枚举不可能,所以需要预先进行离散化.在纵

poj 2482 Stars in Your Window (线段树扫描线)

题目大意: 求一个窗体覆盖最多的星星的权值. 思路分析: 每个星星看成 左下点为x y 右上点为x+w-1 y+h-1 的矩形. 然后求出最大覆盖的和. #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #define lson num<<1,s,mid #define rson num<<1|1,mid+1,e #define

POJ 2482 stars in your window(线段树 , 扫描线)

题目大意: 给你10000以内的星星的坐标和亮度,让你用一个W × H 的矩形去围住一个区域,使得区域内星星的亮度最大,矩形边缘上的星星不算. 解题思路: 对于每一个星星 建立一个(x, y , y + h , c) 的扫描线 和一个(x + w , y , y + h , - c)的扫描线,将问题转化成求区间最大值.几个需要注意的地方:矩形边缘上的需要处理一下,将每个叶节点设为长度为1的线段.另外此题如果用long long wa掉的话可以改为unsigned. #include <iostr