zoukankan      html  css  js  c++  java
  • 线段树专辑 —— pku 2482 Stars in Your Window

    http://poj.org/problem?id=2482

    A了这题后,我就在想,是不是ACMER都找不到女朋友.....

    这题看似很新颖,其实就是求线段树区间最值。所谓区间最值,其实就是和RMQ差不多,只不过RMQ是以点为单位,而这个是以区间为单位。

    怎么扯到区间最值了呢?

    因为每一颗星星,它都有一个亮度,假设这个星星现在正在最左边,那么它的亮度将会影响到向右W的范围。也就是说[star.x,star.x+W]这个区间都会因为这个亮度的影响而加上这个亮度值,最后求一个[x,x+W]的区间,并且该区间的亮度最大,这就是区间最值!方法和RMQ一样,只是不是更新到节点,而是更新到相应线段即可!

    这里还要注意的几个地方

    1、是这个题目要求恰好在窗户上的星星是不算数的,所以我们取区间[x,x+W]的时候,应该取[x,x+W-1]

    2、必须离散化

    3、注意高度上的要求,当最高的和最低的那颗星星的高度差等于或者超过H以后,我们就要减去最低的那颗星星亮度,因为窗户高度是有限的!

    总的来说,就是不容易看出其数学模型,看出来后就很简单了

    View Code
      1 #include<iostream>
    2 #include<string>
    3 #include<algorithm>
    4 using namespace std;
    5
    6 struct node
    7 {
    8 int l;
    9 int r;
    10 __int64 add;
    11 __int64 max_val;
    12 };
    13
    14 node tree[100000];
    15 int n,len;
    16 __int64 H,W;
    17 __int64 xx[20001];
    18
    19 struct star
    20 {
    21 __int64 x,y,c;
    22 };
    23
    24 star num[10001];
    25
    26 int cmp(star a,star b)
    27 {
    28 return a.y<b.y;
    29 }
    30
    31 int find(__int64 x)
    32 {
    33 int l=0,r=len,mid;
    34 while(l<=r)
    35 {
    36 mid=(l+r)/2;
    37 if(xx[mid]==x)
    38 return mid;
    39 if(xx[mid]<x)
    40 l=mid+1;
    41 else
    42 r=mid-1;
    43 }
    44 return l;
    45 }
    46
    47 void build(int i,int l,int r)
    48 {
    49 tree[i].l=l;
    50 tree[i].r=r;
    51 tree[i].add=0;
    52 tree[i].max_val=0;
    53 if(l==r)
    54 return;
    55 int mid=(l+r)/2;
    56 build(2*i,l,mid);
    57 build(2*i+1,mid+1,r);
    58 }
    59
    60 void updata(int i,int l,int r,__int64 c)
    61 {
    62 if(tree[i].l>r || tree[i].r<l)
    63 return;
    64 if(tree[i].l>=l && tree[i].r<=r)
    65 {
    66 tree[i].add+=c;
    67 tree[i].max_val+=c;
    68 return;
    69 }
    70 if(tree[i].add)
    71 {
    72 tree[2*i].add+=tree[i].add;
    73 tree[2*i+1].add+=tree[i].add;
    74 tree[2*i].max_val+=tree[i].add;
    75 tree[2*i+1].max_val+=tree[i].add;
    76 tree[i].add=0;
    77 }
    78 updata(2*i,l,r,c);
    79 updata(2*i+1,l,r,c);
    80 tree[i].max_val=tree[2*i].max_val>tree[2*i+1].max_val?tree[2*i].max_val:tree[2*i+1].max_val;
    81 }
    82
    83 int main()
    84 {
    85 int i,j,m,a,b;
    86 freopen("in.txt","r",stdin);
    87 while(scanf("%d%I64d%I64d",&n,&W,&H)!=EOF)
    88 {
    89 m=0;
    90 for(i=0;i<n;i++)
    91 {
    92 scanf("%I64d%I64d%I64d",&num[i].x,&num[i].y,&num[i].c);
    93 xx[m++]=num[i].x;
    94 xx[m++]=num[i].x+W;
    95 }
    96 sort(xx,xx+m);
    97 len=1;
    98 for(i=1;i<m;i++)
    99 {
    100 if(xx[i-1]!=xx[i])
    101 xx[len++]=xx[i];
    102 }
    103 len--;
    104 build(1,0,len);
    105 sort(num,num+n,cmp);
    106 __int64 ans=0;
    107 for(j=0,i=0;i<n;i++)
    108 {
    109 while(num[i].y-num[j].y>=H) //控制高度范围
    110 {
    111 a=find(num[j].x);
    112 b=find(num[j].x+W)-1;
    113 updata(1,a,b,-num[j].c);
    114 j++;
    115 }
    116 a=find(num[i].x);
    117 b=find(num[i].x+W)-1;
    118 updata(1,a,b,num[i].c);
    119 if(tree[1].max_val>ans)
    120 ans=tree[1].max_val;
    121 }
    122 printf("%I64d\n",ans);
    123 }
    124 return 0;
    125 }



  • 相关阅读:
    sync.WaitGroup golang并发调度器
    Golang New 关键字的小bug 未找到原因(暂时)
    zabbix监控websphere的几个监控项
    zabbix监控AIX DB2数据库
    NOIP2008P 排座椅
    解题报告—— 2018级2016第二学期第五周作业 删数问题
    解题报告——2018级2016第二学期第五周作业排座椅
    解题报告——2018级2016第二学期第四周作业 (2的幂次方)
    解题报告——-2018级2016第二学期第三周作业
    解题报告——2018级2016第二学期第二周作业
  • 原文地址:https://www.cnblogs.com/ka200812/p/2248043.html
Copyright © 2011-2022 走看看