【POJ2482】Stars in Your Window(线段树,扫描线)

题意:在二维坐标系中有一些带权值的点,要求用一个长宽指定不能互换的框套住其中的一些,使得它们的权值和最大。

n<=10000 x,y<=2^31

思路:首先按X排序,将Y坐标离散化,X坐标用扫描线框定,每个点(x,y)在x中只对y有a[i]的贡献,y+h有-a[i]的贡献,线段树(树状数组更好写)维护最大子段和即可。

  1 var t:array[1..200000]of record
  2                            l,r,s,m:int64;
  3                           end;
  4     x,y,c,a,h:array[1..50000]of int64;
  5     n,m,i,j,tt,ww,up,w1,h1:longint;
  6     ans:int64;
  7
  8 procedure swap(var x,y:int64);
  9 var t:int64;
 10 begin
 11  t:=x; x:=y; y:=t;
 12 end;
 13
 14 procedure qsort(l,r:longint);
 15 var i,j,mid1,mid2:longint;
 16 begin
 17  i:=l; j:=r; mid1:=x[(l+r)>>1]; mid2:=y[(l+r)>>1];
 18  repeat
 19   while (mid1>x[i])or((mid1=x[i])and(mid2>y[i])) do inc(i);
 20   while (mid1<x[j])or((mid1=x[j])and(mid2<y[j])) do dec(j);
 21   if i<=j then
 22   begin
 23    swap(x[i],x[j]);
 24    swap(y[i],y[j]);
 25    swap(a[i],a[j]);
 26    inc(i); dec(j);
 27   end;
 28  until i>j;
 29  if l<j then qsort(l,j);
 30  if i<r then qsort(i,r);
 31 end;
 32
 33 procedure qsort2(l,r:longint);
 34 var i,j:longint;
 35     mid:int64;
 36 begin
 37  i:=l; j:=r; mid:=c[(l+r)>>1];
 38  repeat
 39   while mid>c[i] do inc(i);
 40   while mid<c[j] do dec(j);
 41   if i<=j then
 42   begin
 43    swap(c[i],c[j]);
 44    inc(i); dec(j);
 45   end;
 46  until i>j;
 47  if l<j then qsort2(l,j);
 48  if i<r then qsort2(i,r);
 49 end;
 50
 51 function max(x,y:int64):int64;
 52 begin
 53  if x>y then exit(x);
 54  exit(y);
 55 end;
 56
 57 procedure pushup(p:longint);
 58 var ls,rs:longint;
 59 begin
 60  ls:=p<<1; rs:=ls+1;
 61  t[p].l:=max(t[ls].l,t[ls].s+t[rs].l);
 62  t[p].r:=max(t[rs].r,t[rs].s+t[ls].r);
 63  t[p].m:=max(t[ls].r+t[rs].l,max(t[ls].m,t[rs].m));
 64 end;
 65
 66 procedure update(l,r,x,v,p:longint);
 67 var mid:longint;
 68 begin
 69  if l=r then
 70  begin
 71   t[p].s:=t[p].s+v;
 72   t[p].l:=t[p].s; t[p].r:=t[p].s; t[p].m:=t[p].s;
 73   exit;
 74  end;
 75  mid:=(l+r)>>1;
 76  if x<=mid then update(l,mid,x,v,p<<1)
 77   else update(mid+1,r,x,v,p<<1+1);
 78  t[p].s:=t[p].s+v;
 79  pushup(p);
 80 end;
 81
 82 function hash(x:int64):longint;
 83 var l,r,mid,last:longint;
 84 begin
 85  l:=1; r:=up; last:=1;
 86  while l<=r do
 87  begin
 88   mid:=(l+r)>>1;
 89   if x=h[mid] then begin last:=mid; r:=mid-1; end;
 90   if x<h[mid] then r:=mid-1;
 91   if x>h[mid] then l:=mid+1;
 92  end;
 93  exit(last);
 94 end;
 95
 96 begin
 97  assign(input,‘poj2482.in‘); reset(input);
 98  assign(output,‘poj2482.out‘); rewrite(output);
 99  while not eof do
100  begin
101   readln(n,w1,h1);
102   if n=0 then break;
103   for i:=1 to n do read(x[i],y[i],a[i]);
104   qsort(1,n);
105   m:=0;
106   for i:=1 to n do
107   begin
108    inc(m); c[m]:=y[i];
109    inc(m); c[m]:=y[i]+h1;
110   end;
111   qsort2(1,m);
112   up:=1; h[1]:=c[1];
113   for i:=2 to m do
114    if c[i]>c[i-1] then
115    begin
116     if c[i]=c[i-1]+1 then begin inc(up); h[up]:=c[i]; end
117      else
118      begin
119       inc(up); h[up]:=c[i-1];
120       inc(up); h[up]:=c[i];
121      end;
122    end;
123   ans:=-maxlongint;
124   tt:=1; ww:=0;
125   while ww<n do
126   begin
127    inc(ww);
128    while (tt<=n)and(x[tt]+w1-1<x[ww]) do
129    begin
130     update(1,up,hash(y[tt]),-a[tt],1);
131     update(1,up,hash(y[tt]+h1),a[tt],1);
132     inc(tt);
133    end;
134    update(1,up,hash(y[ww]),a[ww],1);
135    update(1,up,hash(y[ww]+h1),-a[ww],1);
136    ans:=max(ans,t[1].m);
137   end;
138   writeln(ans);
139   for i:=1 to up<<2 do
140   begin
141    t[i].s:=0; t[i].l:=0; t[i].r:=0; t[i].m:=0;
142   end;
143  end;
144  close(input);
145  close(output);
146 end.
时间: 2024-11-02 10:23:48

【POJ2482】Stars in Your Window(线段树,扫描线)的相关文章

POJ 2482 Stars in Your Window 线段树扫描线

Stars in Your Window Description Fleeting time does not blur my memory of you. Can it really be 4 years since I first saw you? I still remember, vividly, on the beautiful Zhuhai Campus, 4 years ago, from the moment I saw you smile, as you were walkin

POJ 2482 Stars in Your Window 线段树+离散化+扫描线

题面据说很美- 每个星星可以根据在窗口的左下角和右上角两个位置建立两条扫描线,之后就是简单的区间增减和求最大值操作了. 注意要处理在边界上的星星是不算的情况,其实只要把左右边界分别增减一个eps即可. #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <

POJ 2482 stars in your window(线段树 , 扫描线)

题目大意: 给你10000以内的星星的坐标和亮度,让你用一个W × H 的矩形去围住一个区域,使得区域内星星的亮度最大,矩形边缘上的星星不算. 解题思路: 对于每一个星星 建立一个(x, y , y + h , c) 的扫描线 和一个(x + w , y , y + h , - c)的扫描线,将问题转化成求区间最大值.几个需要注意的地方:矩形边缘上的需要处理一下,将每个叶节点设为长度为1的线段.另外此题如果用long long wa掉的话可以改为unsigned. #include <iostr

【BZOJ】1382: [Baltic2001]Mars Maps (线段树+扫描线)

1382: [Baltic2001]Mars Maps Time Limit: 5 Sec  Memory Limit: 64 MB Description 给出N个矩形,N<=10000.其坐标不超过10^9.求其面积并 Input 先给出一个数字N,代表有N个矩形. 接下来N行,每行四个数,代表矩形的坐标. Output 输出面积并 Sample Input 2 10 10 20 20 15 15 25 30 Sample Output 225 本以为是傻逼题,没想到不容易啊- 线段树+扫描

BZOJ 4059 Cerc2012 Non-boring sequences 线段树+扫描线

题目大意:定义一个序列为[不无聊的]当且仅当这个序列的任意一个区间都存在一个数只出现过一次,给定一个序列,要求判断这个序列是否是[不无聊的] 定义lasti表示第i个元素上一次出现的位置(第一次出现则为0),nexti表示第i个元素下一次出现的位置(最后一次出现则为n+1),那么这个元素能成为某个区间仅出现一次的数,当且仅当这个区间的左端点在[lasti+1,i]之间,右端点在[i,nexti?1]之间 我们可以将区间的左右端点放在二维平面上,那么一个元素产生的贡献是一个矩形,我们要确定的是所有

HDU 4419 Colourful Rectangle --离散化+线段树扫描线

题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何维护每种颜色的长度着实让我伤透了脑筋.后来看了一位朋友的题解,才幡然醒悟. 开始想到了用二进制表示颜色,R用001表示,G用010表示,B用100表示.那么就可以用十进制1~7表示7种不同颜色了. 维护 cov[rt][1~3] 表示此区间内3种原色各有多少个, Len[rt][i]表示每种颜色的长

sgu316Kalevich Strikes Back(线段树+扫描线)

做法:总体想法是求出一个矩形的面积以及它所包含的矩形,然后用自己的面积减掉所包含的.主要问题是怎样求解它所包含的矩形. 因为是没有相交点的,可以利用扫描线的方法去做,类似染色,当前段如果是x色,也就是第x个矩形,那么再把他染成y颜色时,说明x包含y,而当扫到y的上边时,这一段又恢复到x色.标记一下被包含的矩形,记录所包含的矩形. 因为会有恢复染色操作,up需要时时更新,左儿子和右儿子一样颜色时就可以合并为一段. 1 ; 2 } 3 void down(int w) 4 { 5 if(s[w]!=

hdu1255 覆盖的面积 线段树-扫描线

矩形面积并 线段树-扫描线裸题 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<math.h> 5 using namespace std; 6 const int maxm=2e3+5; 7 const double eps=1e-5; 8 9 struct seg{ 10 double x,y1,y2; 11 int c; 12 bool operator

线段树+扫描线 HDOJ 5091 Beam Cannon

题目传送门 1 /* 2 题意:给出若干个点的坐标,用一个矩形去覆盖,问最多能覆盖几个点 3 线段树+扫描线:思路是先建一棵以[y, y + h]的树,左右儿子[x, x + w] 4 以这棵树为范围,从左到右扫描,更新点数,x的+1, x+w的-1(超过矩形范围) 5 ans = 每次更新时所覆盖点数的最大值 6 */ 7 #include <cstdio> 8 #include <algorithm> 9 #include <iostream> 10 #includ

POJ 3277 City Horizon(线段树+扫描线+离散化)

题目地址:POJ 3277 水题..稍微处理一下然后用求面积并的方法求即可. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #include <