zoukankan      html  css  js  c++  java
  • poj 2482 Stars in Your Window(线段树+离散化+线扫描)

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

    大意:在一个坐标系中给你n(10^4)个点(点的坐标范围为0<=x,y<2^31),每个点有一个权值,然后给你一个长宽分别为w,h(10^6)的矩形(平行于坐标轴);
    现在你的任务就是求出用这个矩形所覆盖的点的权值和的最大值(矩形边上的点不算)(矩形可以平移但是不能旋转)

    思路:每个星星都可以以它自己为矩形的左下角(不能包括矩形边),那么就有n个矩形,就转化成了黑书上的第108页的题目,即统计所有1x1的小方格被覆盖的矩形最多的;

          由于点的数量很小,但是坐标的范围很大,于是需要离散化;

      自左向右扫描,左右竖线(在程序中用正负表示)标志矩形进入和退出阴影区域,利用线段树进行更新;

    代码:

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 const int maxn=10010;
      7 struct node
      8 {
      9     __int64 id;//坐标值
     10     int flag;//标记左边还是右边
     11     int xh;//序号
     12 }sx[maxn*2],sy[maxn*2];
     13 struct bj
     14 {
     15     int y1,y2;
     16     int val;//左进右出,左为正,有为负
     17 }line[maxn*2];
     18 int n;
     19 int tree[maxn*8];
     20 int lz[maxn*8];//懒惰标记
     21 bool cmp(struct node a,struct node b)
     22 {
     23     if(a.id==b.id)
     24     return a.flag>b.flag;
     25     return a.id<b.id;
     26 }
     27 void disper()//离散化
     28 {
     29     sort(sx,sx+(n<<1),cmp);
     30     sort(sy,sy+(n<<1),cmp);
     31     int temp=sy[0].id;
     32     int tg=1;
     33     int i;
     34     for(i=0;i<n*2;i++)
     35     {
     36         if(temp!=sy[i].id)
     37         {
     38             tg++;
     39             temp=sy[i].id;
     40         }
     41         if(sy[i].flag)
     42         {
     43             line[sy[i].xh*2].y2=tg;
     44             line[sy[i].xh*2+1].y2=tg;
     45         }
     46         else
     47         {
     48             line[sy[i].xh*2].y1=tg;
     49             line[sy[i].xh*2+1].y1=tg;
     50         }
     51     }
     52 }
     53 void build(int l,int r,int w)
     54 {
     55     tree[w]=0;
     56     lz[w]=0;
     57     if(l==r)
     58     {
     59         return ;
     60     }
     61     int m=(l+r)>>1;
     62     build(l,m,w<<1);
     63     build(m+1,r,w<<1|1);
     64 }
     65 
     66 void update(int l,int r,int w,int L,int R,int val)
     67 {
     68     if(L<=l&&R>=r)
     69     {
     70         tree[w]+=val;
     71         lz[w]+=val;//延迟标记
     72         return ;
     73     }
     74     if(lz[w]!=0)//取消标记
     75     {
     76         lz[w<<1|1]+=lz[w];
     77         lz[w<<1]+=lz[w];
     78         tree[w<<1]+=lz[w];
     79         tree[w<<1|1]+=lz[w];
     80         lz[w]=0;
     81     }
     82     int m=(l+r)>>1;
     83     if(L>m)
     84     update(m+1,r,w<<1|1,L,R,val);
     85     else if(R<=m)
     86     update(l,m,w<<1,L,R,val);
     87     else
     88     {
     89         update(l,m,w*2,L,m,val);
     90         update(m+1,r,w<<1|1,m+1,R,val);
     91     }
     92     tree[w]=max(tree[w<<1],tree[w<<1|1]);
     93 }
     94 int main()
     95 {
     96     int w,h;
     97     while(scanf("%d%d%d",&n,&w,&h)!=EOF)
     98     {
     99         int i;
    100         __int64 x,y;
    101         int valu;
    102         for(i=0;i<n;i++)
    103         {
    104             scanf("%I64d%I64d%d",&x,&y,&valu);
    105             sx[i<<1].id=x;
    106             sx[i<<1].flag=0;//左边
    107             sx[i<<1|1].id=x+w;
    108             sx[i<<1|1].flag=1;//右边
    109             sx[i<<1|1].xh=sx[i<<1].xh=i;
    110 
    111             sy[i<<1].id=y;
    112             sy[i<<1].flag=0;
    113             sy[i<<1|1].id=y+h;
    114             sy[i<<1|1].flag=1;
    115             sy[i<<1|1].xh=sy[i<<1].xh=i;
    116 
    117             line[i<<1].val=valu;
    118             line[i<<1|1].val=-valu;
    119         }
    120         disper();//离散化
    121         /*for(i=0;i<n*2;i++)
    122         {
    123             printf("%d %d %d
    ",line[i].yd,line[i].yu,line[i].val);
    124         }*/
    125         n=n*2;
    126         build(1,n,1);
    127 
    128         int id;
    129         int ans=0;
    130         for(i=0;i<n;i++)//扫描
    131         {
    132             id=sx[i].xh*2+sx[i].flag;
    133             line[id].y1++;//不包括边
    134             update(1,n,1,line[id].y1,line[id].y2,line[id].val);
    135             if(ans<tree[1])
    136             ans=tree[1];
    137         }
    138         printf("%d
    ",ans);
    139     }
    140     return 0;
    141 }
    View Code
  • 相关阅读:
    PAT 天梯赛 L2-003. 月饼 【贪心】
    PAT 天梯赛 L2-015. 互评成绩 【排序】
    PAT 天梯赛 L1-046. 整除光棍 【模拟除法】
    PAT 天梯赛 L1-006. 连续因子 【循环】
    PAT 天梯赛 L1-009. N个数求和 【模拟】
    HackerRank
    ZOJ 3961 Let's Chat 【水】
    ZOJ 3960 What Kind of Friends Are You? 【状态标记】
    ZOJ 3959 Problem Preparation 【水】
    ZOJ 3958 Cooking Competition 【水】
  • 原文地址:https://www.cnblogs.com/wanglin2011/p/3150107.html
Copyright © 2011-2022 走看看