zoukankan      html  css  js  c++  java
  • 【洛谷P1502】窗口的星星

    好像跟POJ重题

    这是一道扫描线的题。

    由于窗口的大小已知,我们不妨换一下思路,把问题转化成这样:平面内有若干个矩形(大小就是窗口的大小,矩形左下角的位置就是某一颗星星的位置),每一个矩形覆盖的区域都有一个权值(星星的亮度),求某一位置,使得这个位置被覆盖的权值最大,最大值即答案。

    为什么这样就是正确的?每一个窗口的大小都是固定的,假设我们把这个窗口的右上角放在刚刚所说的星星的矩形中,那么这颗星星一定能被看见。以此类推,假设我们把窗口的右上角放在尽可能多矩形的范围内(这里说的不太恰当,应该是放在权值加起来尽可能大的范围内),我们的答案就尽可能优,因此,我们只需要用扫描线求出最大的权值即可。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 const int N=10010;
     7 int T;
     8 struct line {
     9     int x,y1,y2,v;
    10     bool operator <(const line &xx) const {
    11         if(x==xx.x) return v>xx.v;
    12         return x<xx.x;
    13     }
    14 }a[N<<1];
    15 int n,val[N<<1][2],raw[N<<1];
    16 struct node {
    17     int l,r;
    18     int data,tag;
    19 }s[N<<3];
    20 int ans,t,w,h;
    21 inline void build(int now,int l,int r) {
    22     s[now].l=l;
    23     s[now].r=r;
    24     s[now].data=s[now].tag=0;
    25     if(l==r) return ;
    26     int mid=l+r>>1;
    27     build(now<<1,l,mid);
    28     build(now<<1|1,mid+1,r);
    29 }
    30 inline void pushdown(int now) {
    31     if(s[now].tag) {
    32         int v=s[now].tag;
    33         s[now<<1].tag+=v;
    34         s[now<<1|1].tag+=v;
    35         s[now<<1].data+=v;
    36         s[now<<1|1].data+=v;
    37         s[now].tag=0;
    38     }
    39 }
    40 void updata(int now,int l,int r,int v) {
    41     if(l<=s[now].l&&s[now].r<=r) {
    42         s[now].data+=v;
    43         s[now].tag+=v;
    44         return ;
    45     }
    46     pushdown(now);
    47     int mid=s[now].l+s[now].r>>1;
    48     if(l<=mid) updata(now<<1,l,r,v);
    49     if(r>mid) updata(now<<1|1,l,r,v);
    50     s[now].data=max(s[now<<1].data,s[now<<1|1].data);
    51 }
    52 int main() {
    53     scanf("%d",&T);
    54     while(T--) {
    55         ans=t=0;
    56         scanf("%d%d%d",&n,&w,&h);
    57         for(int i=1;i<=n;i++) {
    58             int x,y,z;
    59             scanf("%d%d%d",&x,&y,&z);
    60             a[2*i-1]=(line){x,y,y+h,z};
    61             a[2*i]=(line){x+w-1,y,y+h,-z};
    62             raw[++t]=y;
    63             raw[++t]=y+h-1;
    64         }
    65         sort(a+1,a+2*n+1);
    66         sort(raw+1,raw+t+1);
    67         t=unique(raw+1,raw+t+1)-raw-1;
    68         for(int i=1;i<=2*n;i++) {
    69             val[i][0]=lower_bound(raw+1,raw+t+1,a[i].y1)-raw;
    70             val[i][1]=lower_bound(raw+1,raw+t+1,a[i].y2)-raw;
    71         }
    72         build(1,1,t);
    73         for(int i=1;i<=2*n;i++) {
    74             updata(1,val[i][0],val[i][1]-1,a[i].v);
    75             ans=max(ans,s[1].data);
    76         }
    77         printf("%d
    ",ans);
    78     }
    79     return 0;
    80 }
    AC Code
  • 相关阅读:
    HDU
    HDU
    POJ
    HDU
    HDU
    POJ
    HDU
    FZU
    LightOJ 1030 Discovering Gold 数学期望计算
    POJ 3061 Subsequence 二分查找
  • 原文地址:https://www.cnblogs.com/shl-blog/p/10960214.html
Copyright © 2011-2022 走看看