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 }



  • 相关阅读:
    关于celery踩坑
    关于git的分批提交pull requests流程
    SymGAN—Exploiting Images for Video Recognition: Heterogeneous Feature Augmentation via Symmetric Adversarial Learning学习笔记
    AFN—Larger Norm More Transferable: An Adaptive Feature Norm Approach for Unsupervised Domain Adaptation学习笔记
    Learning to Transfer Examples for Partial Domain Adaptation学习笔记
    Partial Adversarial Domain Adaptation学习笔记
    Partial Transfer Learning with Selective Adversarial Networks学习笔记
    Importance Weighted Adversarial Nets for Partial Domain Adaptation学习笔记
    Exploiting Images for Video Recognition with Hierarchical Generative Adversarial Networks学习笔记
    improved open set domain adaptation with backpropagation 学习笔记
  • 原文地址:https://www.cnblogs.com/ka200812/p/2248043.html
Copyright © 2011-2022 走看看