bzoj 1007 凸壳

首先明确一个概念

左面内个叫上凸壳,右面那个叫下凸壳

然后我们只需要维护一个上图壳就行了,先按着斜率排序,每次加进来一条边,判断tot边和这个边与tot-1边的交点横坐标,

如果这条边的横坐标小就一直弹栈就好了

/**************************************************************
    Problem: 1007
    User: BLADEVIL
    Language: Pascal
    Result: Accepted
    Time:360 ms
    Memory:3352 kb
****************************************************************/
 
//By BLADEVIL
var
    n                       :longint;
    a, b, num               :array[0..100010] of longint;
    quea, queb              :array[0..100010] of longint;
    tot                     :longint;
    quex                    :array[0..100010] of double;
    ans                     :array[0..100010] of longint;
    i                       :longint;
     
procedure swap(var a,b:longint);
var
    c                       :longint;
begin
    c:=a; a:=b; b:=c;
end;
     
procedure qs(low,high:longint);
var
    i, j, xx, yy            :longint;
begin
    i:=low; j:=high; xx:=a[(i+j) div 2];
    yy:=b[(i+j) div 2];
    while i<j do
    begin
        while (a[i]<xx) or (a[i]=xx) and (b[i]>yy) do inc(i);
        while (a[j]>xx) or (a[j]=xx) and (b[j]<yy) do dec(j);
        if i<=j then
        begin
            swap(a[i],a[j]);
            swap(b[i],b[j]);
            swap(num[i],num[j]);
            inc(i); dec(j);
        end;
    end;
    if i<high then qs(i,high);
    if j>low then qs(low,j);
end;
 
procedure qs1(low,high:longint);
var
    i, j, xx                :longint;
begin
    i:=low; j:=high; xx:=ans[(i+j) div 2];
    while i<j do
    begin
        while ans[i]<xx do inc(i);
        while ans[j]>xx do dec(j);
        if i<=j then
        begin
            swap(ans[i],ans[j]);
            inc(i); dec(j);
        end;
    end;
    if i<high then qs1(i,high);
    if j>low then qs1(low,j);
end;
     
procedure insert(i:longint);
var
    k                       :longint;
    x                       :double;
begin
    if a[i]=quea[tot] then exit;
    if tot>1 then
    begin
        x:=(queb[tot-1]-b[i])/(a[i]-quea[tot-1]);
        while (tot>1) and (x<=quex[tot]) do
        begin
            dec(tot);
            x:=(queb[tot-1]-b[i])/(a[i]-quea[tot-1]);
        end;
    end;
    inc(tot);
    quea[tot]:=a[i];
    queb[tot]:=b[i];
    quex[tot]:=(queb[tot-1]-b[i])/(a[i]-quea[tot-1]);
    ans[tot]:=num[i];
end;
     
begin
    read(n);
    for i:=1 to n do read(a[i],b[i]);
    for i:=1 to n do num[i]:=i;
    qs(1,n);
    quea[1]:=a[1]; queb[1]:=b[1]; 
    quex[1]:=-maxlongint; ans[1]:=num[1];
    tot:=1;
    for i:=2 to n do insert(i);
    qs1(1,tot);
    for i:=1 to tot do write(ans[i],' ');
end.

 

posted on 2013-12-12 11:27  BLADEVIL  阅读(709)  评论(0编辑  收藏  举报