zoukankan      html  css  js  c++  java
  • poj2482

    (题外话:这题这是ACMer的福利啊……)
    我非常不擅长做矩形类的数据结构
    一般来说,二维的问题我们要转化为一维来考虑
    感觉一般的手法是对一维排序,并且线性扫描这一维,然后用各种数据结构维护另一维上的最优值
    这道题我们首先对x排序,然后扫描x坐标
    这时候我们要维护2条扫描线,一左一右(应该就是two pointer)
    扫描线之间的长度就是要求小于等于窗口宽度
    随着右扫描线的移动,我们把这条扫描线上的点加到某个数据结构中
    随着左扫描线的移动,我们把这条扫描线的点删除
    显然每个点添加一次且删除一次,要做O(n)次操作
    下面我们要做的就是在给定的横坐标区域内,找出星星亮度和最大的窗口
    显然这里横坐标区域中的每一个点我们都可以当作压缩在一条线上考虑
    考虑求数列区间长度小于等于h的和的最大值,我们对于每一个位置x上的元素a[x]
    在x+h的位置上加上-a[x],然后我们可以用线段树维护区间最大和
    这个区间最大和长度一定是小于等于h的(想想为什么)
    这里的线段树是单点修改,直接查询(难得不用lazy tag,但是要用lmax,rmax)
    所以操作的复杂度为O(logn),查询O(1),总的复杂度为O(nlogn)
    注意y的坐标很大,要离散化

      1 var tree,lmax,rmax,maxx,c,rank:array[0..80010] of longint;
      2     a:array[0..20010] of int64;
      3     x,y,s:array[0..10010] of longint;
      4     w,h,n,m,t,p,l,i,ans:longint;
      5 
      6 function max(a,b:longint):longint;
      7   begin
      8     if a>b then exit(a) else exit(b);
      9   end;
     10 
     11 procedure swap(var a,b:longint);
     12   var c:longint;
     13   begin
     14     c:=a;
     15     a:=b;
     16     b:=c;
     17   end;
     18 
     19 procedure sorty(l,r: longint);
     20   var i,j: longint;
     21       x,y:int64;
     22   begin
     23     i:=l;
     24     j:=r;
     25     x:=a[(l+r) shr 1];
     26     repeat
     27       while a[i]<x do inc(i);
     28       while x<a[j] do dec(j);
     29       if not(i>j) then
     30       begin
     31         y:=a[i];
     32         a[i]:=a[j];
     33         a[j]:=y;
     34 
     35         swap(c[i],c[j]);
     36         inc(i);
     37         j:=j-1;
     38       end;
     39     until i>j;
     40     if l<j then sorty(l,j);
     41     if i<r then sorty(i,r);
     42   end;
     43 
     44 procedure sortx(l,r: longint);
     45   var i,j,z: longint;
     46   begin
     47     i:=l;
     48     j:=r;
     49     z:=x[(l+r) shr 1];
     50     repeat
     51       while x[i]<z do inc(i);
     52       while z<x[j] do dec(j);
     53       if not(i>j) then
     54       begin
     55         swap(x[i],x[j]);
     56         swap(y[i],y[j]);
     57         swap(s[i],s[j]);
     58         inc(i);
     59         j:=j-1;
     60       end;
     61     until i>j;
     62     if l<j then sortx(l,j);
     63     if i<r then sortx(i,r);
     64   end;
     65 
     66 procedure work(i,l,r,x,z:longint);
     67   var m:longint;
     68   begin
     69     if l=r then
     70     begin
     71       inc(tree[i],z);
     72       lmax[i]:=tree[i];
     73       rmax[i]:=tree[i];
     74       maxx[i]:=tree[i];
     75     end
     76     else begin
     77       m:=(l+r) shr 1;
     78       if x<=m then work(i*2,l,m,x,z)
     79       else work(i*2+1,m+1,r,x,z);
     80       inc(tree[i],z);
     81       lmax[i]:=max(lmax[i*2],tree[i*2]+lmax[i*2+1]);   //不多说
     82       rmax[i]:=max(rmax[i*2+1],tree[i*2+1]+rmax[i*2]);
     83       maxx[i]:=max(lmax[i*2+1]+rmax[i*2],max(maxx[i*2],maxx[i*2+1]));
     84     end;
     85   end;
     86 
     87 begin
     88   while not eof do
     89   begin
     90     readln(n,w,h);
     91     for i:=1 to n do
     92       readln(x[i],y[i],s[i]);
     93     sortx(1,n);
     94 //先对x排序,后面离散化y坐标对应就轻松一点
     95     for i:=1 to n do
     96     begin
     97       a[i]:=y[i];
     98       a[i+n]:=int64(y[i])+int64(h);//当然y+h这个位置也要离散化
     99       c[i]:=i;
    100       c[i+n]:=i+n;  
    101     end;
    102     t:=n*2;
    103     sorty(1,t);
    104     p:=1;
    105     rank[c[1]]:=1;
    106     for i:=2 to t do
    107     begin
    108       if (a[i]<>a[i-1]) then inc(p);
    109       rank[c[i]]:=p;
    110     end;
    111     m:=p;
    112     fillchar(tree,sizeof(tree),0);
    113     fillchar(lmax,sizeof(lmax),0);
    114     fillchar(rmax,sizeof(rmax),0);
    115     fillchar(maxx,sizeof(maxx),0);
    116     l:=1;
    117     ans:=0;
    118     for i:=1 to n do
    119     begin
    120       while (l<i) and (int64(x[l])+int64(w)<=x[i])  do
    121       begin
    122         work(1,1,m,rank[l],-s[l]);   //删除左扫描线左边的点
    123         work(1,1,m,rank[l+n],s[l]);
    124         inc(l);
    125       end;
    126       work(1,1,m,rank[i+n],-s[i]);   //右加入扫描线上的点
    127       work(1,1,m,rank[i],s[i]);
    128       ans:=max(ans,maxx[1]);
    129     end;
    130     writeln(ans);
    131   end;
    132 end.
    View Code
  • 相关阅读:
    Linux 套接字编程
    Linux 网络(连接)相关参数作用
    Python WSGI
    Ubuntu Cloud Image in Openstack
    AWK
    MySQL--开发技巧(一)
    spring MVC--配置注解
    javascript-JQuery样式篇(一)
    JSP--常用标签
    spring MVC basic
  • 原文地址:https://www.cnblogs.com/phile/p/4473141.html
Copyright © 2011-2022 走看看