[HNOI2012]archery

题意:略

思路:略

实践证明:单纯形法比裸半平面交(nlog^2n)略快!!!!!!

半平面交(nlogn)的code:

program std;
uses math;
type
        int=longint;
        real=extended;
        point=record
                x,y:real;
        end;//(x,y)
        line=record
                a,b,c:real;
        end;//ax+by>c
const e=1e-16;maxn=400000;

operator **(a,b:point)c:real;
begin c:=a.x*b.x+a.y*b.y;end;{dian ji}

operator *(a,b:point)c:real;
begin c:=a.x*b.y-a.y*b.x;end;{cha ji}

operator *(a,b:line)c:point;
var s,x,y:real;
begin
        s:=a.b*b.a-a.a*b.b;
        x:=a.b*b.c-a.c*b.b;
        y:=a.a*b.c-a.c*b.a;
        c.x:=x/s;c.y:=-y/s;
end;

procedure get(var x:real;y:real);
begin
        x:=y+(random(1000)/1000000)*e;
end;

var
        l,r,mid,i,j,k,m,n:int;
        t,d:real;
        a:array[1..2*maxn]of line;
        x,y,z,s:array[1..maxn]of real;
        p,q:array[1..2*maxn]of int;
        c:array[1..2*maxn]of point;

procedure sort(l,r:int);var i,j:int;
begin
        i:=l;j:=r;
        d:=s[p[(l+r)>>1]];
        repeat
                while s[p[i]]<d do inc(i);
                while s[p[j]]>d do dec(j);
                if i<=j then begin
                        k:=p[i];p[i]:=p[j];p[j]:=k;
                        inc(i);dec(j);
                end;
        until i>j;
        if i<r then sort(i,r);
        if j>l then sort(l,j);
end;

procedure ins(x,y,z:real);
begin
        inc(m);p[m]:=m;
        get(a[m].a,x);get(a[m].b,y);get(a[m].c,z);
        s[m]:=arctan2(x,y);
end;

function ok(n:int):boolean;var h,r:int;l:line;
begin
        n:=n*2+4;
        h:=2;r:=2;q[1]:=p[1];q[2]:=p[2];
        c[2]:=a[p[1]]*a[p[2]];
        for i:=3 to m do if p[i]<=n then begin
                l:=a[p[i]];
                while(r>=h)and(c[r].x*l.a+c[r].y*l.b<l.c)do dec(r);
                while(h<=r)and(c[h].x*l.a+c[h].y*l.b<l.c)do inc(h);
                inc(r);q[r]:=p[i];
                c[r]:=a[q[r-1]]*l;
        end;
        l:=a[q[r]];
        while(h<=r)and(c[h].x*l.a+c[h].y*l.b<l.c)do inc(h);
        l:=a[q[h-1]];
        while(r>=h)and(c[r].x*l.a+c[r].y*l.b<l.c)do dec(r);
        ok:=h<>r;
end;

begin
        assign(input,'archery.in');reset(input);
        assign(output,'archery.out');rewrite(output);
        read(n);
        for i:=1 to n do read(x[i],y[i],z[i]);
        m:=0;
        ins(1,0,-1e+20);ins(0,-1,-1e+20);
        ins(-1,0,0);ins(0,1,0);
        for i:=1 to n do begin
                ins(x[i]*x[i],x[i],y[i]);
                ins(-x[i]*x[i],-x[i],-z[i]);
        end;
        sort(1,m);
        l:=0;r:=n+1;
        while l<>r-1 do begin
                mid:=(l+r)>>1;
                if ok(mid)then l:=mid
                        else r:=mid;
        end;
        write(l);
        close(input);close(output);
end.

其实半平面交也不长.

单纯形的程序以后再搞上来.

无数事实表明,虽然单纯形法的复杂度几乎无法估计,但实际的效果还是很好的.

另外,这个程序没有判平行的情况,所以精度很成问题.但是因为hnoi的数据过水,所以就懒得改了....

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值