现在的位置: 首页 > 综合 > 正文

poj2482

2018年04月26日 ⁄ 综合 ⁄ 共 2540字 ⁄ 字号 评论关闭

【题意】

前面是一段英文情书

给定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.
【上篇】
【下篇】

抱歉!评论已关闭.