• 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.
  • 相关阅读:
    Git push 出错 [The remote end hung up unexpectedly]
    [Git高级教程(二)] 远程仓库版本回退方法
    git分支与版本管理、版本回退、冲突解决记录
    上传本地代码到gitHub过程详解
    如何用git将项目代码上传到github
    Git pull 强制覆盖本地文件
    Git忽略规则.gitignore梳理
    composer本地安装文档
    服务器通过微信公众号Token验证测试的代码(Python版)
    转载自lanceyan: 一致性hash和solr千万级数据分布式搜索引擎中的应用
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3470781.html
Copyright © 2020-2023  润新知