• poj 2482 Stars in Your Window 线段树


    题意:平面上有n个星星,给出每个星星的位置和亮度 求一个W*H的矩形(不包括边界)使得矩形内的星星亮度之和最大。
     
    思路:每个点(x,y,brightness) 存两个点(x,y,brightness)和(x,y+H,-brightness)
    先离散化
    从左到右两根间距为W的扫描线,左开右闭。依次把点加进线段树,下标是y,权值是brightness,题目所求的就是前i个点的和的最大值。
    线段树存当前范围内的sum,maxsum
    其中 maxsum[i]=max(maxsum[2*i],sum[2*i]+maxsum[2*i+1]);
    ans=max(maxsum[i])
     
      1 #include<iostream>
    2 #include<algorithm>
    3 #include<cmath>
    4 using namespace std;
    5 #define MAXN 20002
    6 struct node
    7 {
    8 int sum,maxsum;
    9 int left,right;
    10 };
    11 struct star
    12 {
    13 long long x,y;
    14 int degree;
    15 int id;
    16 };
    17 node tree[MAXN*4];
    18 star a[MAXN];
    19 int home[MAXN];
    20 int width,high;
    21 int n;
    22 void buildtree(int i)
    23 {
    24 tree[i].sum=tree[i].maxsum=0;
    25 if(tree[i].left==tree[i].right)
    26 return ;
    27 int mid=(tree[i].left+tree[i].right)/2;
    28 tree[2*i].left=tree[i].left; tree[2*i].right=mid;
    29 tree[2*i+1].left=mid+1; tree[2*i+1].right=tree[i].right;
    30 buildtree(2*i); buildtree(2*i+1);
    31 }
    32 bool cmp1(const star &x,const star &y)
    33 {
    34 if(x.y<y.y) return 1;
    35 if(x.y==y.y&&x.x<y.x) return 1;
    36 return 0;
    37 }
    38 bool cmp2(const star &x,const star &y)
    39 {
    40 return x.x<y.x;
    41 }
    42 void insert(int i,int x,int add)
    43 {
    44 if(tree[i].left==tree[i].right)
    45 {
    46 tree[i].maxsum=tree[i].sum=tree[i].sum+add;
    47 return ;
    48 }
    49 int mid=(tree[i].left+tree[i].right)/2;
    50 if(x<=mid) insert(2*i,x,add);
    51 else insert(2*i+1,x,add);
    52 tree[i].sum+=add;
    53 tree[i].maxsum=max(tree[2*i].sum+tree[2*i+1].maxsum,tree[2*i].maxsum);
    54 }
    55 int main()
    56 {
    57 while(scanf("%d%d%d",&n,&width,&high)!=EOF)
    58 {
    59 int i,j,k;
    60
    61 int x,y,z;
    62 for(i=1;i<=n;i++)
    63 {
    64 scanf("%lld%lld%d",&a[i].x,&a[i].y,&a[i].degree);
    65 a[i].id=i; a[i+n].id=i+n;
    66 a[i+n].x=a[i].x; a[i+n].y=a[i].y+high; a[i+n].degree=-a[i].degree;
    67 }
    68 n=2*n;
    69 sort(a+1,a+n+1,cmp1);
    70 j=0;
    71 a[j].x=-1; a[j].y=-1;
    72 for(i=1;i<=n;i++)
    73 {
    74 if(a[i].y==a[j].y&&a[i].x==a[j].x)
    75 {
    76 a[j].degree+=a[i].degree;
    77 }
    78 else
    79 {
    80 j++; a[j].x=a[i].x; a[j].y=a[i].y; a[j].id=a[i].id; a[j].degree=a[i].degree;
    81 home[a[j].id]=j;
    82 }
    83 }
    84 n=j;
    85 tree[1].left=1; tree[1].right=n;
    86 buildtree(1);
    87 sort(a+1,a+n+1,cmp2);
    88 long long l1,l2;
    89 l1=a[1].x; l2=l1+width;
    90 i=1; j=0;
    91 int ans=0;
    92 while(j<n)
    93 {
    94 if(a[i].x-l1<=a[j+1].x-l2)//必须是小于等于 左开右闭
    95 {
    96 l1=a[i].x;
    97 while(a[i].x==l1)//每次一定要把线上的所有点都处理了
    98 {
    99 insert(1,home[a[i].id],-a[i].degree); i++;
    100 }
    101 l2=l1+width;
    102 }
    103 else
    104 {
    105 l2=a[j+1].x;
    106 while(a[j+1].x==l2)
    107 {
    108 j++; insert(1,home[a[j].id],a[j].degree);
    109 }
    110 l1=l2-width;
    111 }
    112 if(tree[1].maxsum>ans) ans=tree[1].maxsum;
    113 }
    114 printf("%d\n",ans);
    115 }
    116 return 0;
    117 }
      
  • 相关阅读:
    2021.07.11 【ABAP随笔】采购订单Message输出打印
    项目管理43210学习笔记
    Rails跳过回调方法
    树莓派接USB温湿度传感器(python)
    Visual Studio2019安装时报错Microsoft.Net.4.7.2.FullRedist的解决方法
    微信浏览器中H5使用wx-open-launch-app打开第三方APP
    Linux系统使用qq邮箱在线发送邮件
    LRU工程实现源码(一):Redis 内存淘汰策略
    Android Studio解决Build Log出现乱码问题
    git新拉取项目
  • 原文地址:https://www.cnblogs.com/myoi/p/2343138.html
Copyright © 2020-2023  润新知