【题意】
前面是一段英文情书
给定n个星星的坐标和亮度,求一个位置任意w*h的矩形内最大亮度和(矩形下边界和左边界上的星星不算)
【输入】
多组数据
每组数据开头一行为三个数字n(n<=10000),w,h
接下来n行分别为该星星的横纵坐标和亮度(longint级)
【输出】
对于每组数据输出一个数字表示最大亮度和
求任意一块面积内的亮度和非常麻烦,这题用到了一个转化
对于一个坐标为x,y的亮度为b的星星,在x,y+h的位置添加一个-b的星星
按y值从小到大将星星一行一行的插入,然后这道题就转化为了求最大元素的问题
需要注意y+h会超过longint级
因为x的跨度比较大,所以最好离散一下
program poj2482; type arr=array [0..20001] of int64; var n,w,h,i,j,k,all,tot:longint; ans:int64; num,xl,dl,b,x,y:arr; maxn:array [0..300001] of int64; change,left,right:array [0..300001] of longint; procedure build ; begin inc(tot); left[tot]:=0; right[tot]:=0; change[tot]:=0; maxn[tot]:=0; end; procedure down (now:longint); begin if left[now]=0 then begin build; left[now]:=tot; end; if right[now]=0 then begin build; right[now]:=tot; end; if change[now]=0 then exit; maxn[left[now]]:=maxn[left[now]]+change[now]; change[left[now]]:=change[left[now]]+change[now]; maxn[right[now]]:=maxn[right[now]]+change[now]; change[right[now]]:=change[right[now]]+change[now]; change[now]:=0; end; function quick (now:longint):longint; var s,e,mid:longint; begin s:=now; e:=all; while s<>e do begin mid:=s+e-(s+e) div 2; if num[mid]-num[now]<w then s:=mid else e:=mid-1; end; exit(s); end; procedure swap (var a,b:int64); var i:int64; begin i:=a; a:=b; b:=i; end; procedure qsort (s,e:longint;var x,dl:arr); var i,j:longint; k:int64; begin if s>=e then exit; i:=s; j:=e; k:=x[dl[(s+e) div 2]]; while i<=j do begin while x[dl[i]]<k do inc(i); while x[dl[j]]>k do dec(j); if i>j then break; swap(dl[i],dl[j]); inc(i); dec(j); end; qsort(s,j,x,dl); qsort(i,e,x,dl); end; function hash (p:int64):int64; var mid,s,e:longint; begin s:=1; e:=all; repeat mid:=(s+e) div 2; if p=num[mid] then exit(mid) else if p>num[mid] then s:=mid+1 else e:=mid-1; until false; end; procedure insert (s,e,p,l,r,now:longint); var mid:longint; begin if (s=l)and(e=r) then begin maxn[now]:=maxn[now]+p; change[now]:=change[now]+p; exit; end; mid:=(l+r) div 2; down(now); if e<=mid then insert(s,e,p,l,mid,left[now]) else if s>mid then insert(s,e,p,mid+1,r,right[now]) else begin insert(s,mid,p,l,mid,left[now]); insert(mid+1,e,p,mid+1,r,right[now]); end; if maxn[left[now]]>maxn[right[now]] then maxn[now]:=maxn[left[now]] else maxn[now]:=maxn[right[now]] end; begin while not seekeof do begin read(n,w,h); for i:=1 to n do begin read(x[i],y[i],b[i]); x[i+n]:=x[i]; y[i+n]:=y[i]+h; b[i+n]:=-b[i]; end; n:=n*2; for i:=1 to n do dl[i]:=i; for i:=1 to n do xl[i]:=i; qsort(1,n,y,dl); qsort(1,n,x,xl); x[xl[0]]:=-100000; k:=0; all:=0; for i:=1 to n do if x[xl[i]]<>x[xl[k]] then begin inc(all); num[all]:=x[xl[i]]; k:=i; end; k:=1; i:=1; ans:=0; tot:=-1; build; repeat while (i<=n)and(y[dl[i]]=y[dl[k]]) do begin insert(hash(x[dl[i]]),quick(hash(x[dl[i]])),b[dl[i]],1,all,0); inc(i); end; if maxn[0]>ans then ans:=maxn[0]; k:=i; until i>n; writeln(ans); end; end.