BZOJ1137: [POI2009]Wsp 岛屿

来源:互联网 发布:程序员交流圈 编辑:程序博客网 时间:2024/05/16 05:55

看错题了qwq

看对题了也不会呀…
题解说是半平面交裸题
于是学了一下半平面交
贴个板子qwq

code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;inline void read(int &x){    char c; bool flag=true;    while(!((c=getchar())>='0'&&c<='9')) if(c=='-') flag=false;    x=c-'0';    while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';    if(!flag) x=-x;}const int maxn = 110000;const int maxm = 1100000;const double eps = 1e-12;const double pi = acos(-1);const double pi2= pi/2.0;inline double sqr(const double x){return x*x;}int n,m;struct point{double x,y;}p[maxn];inline double dis(const point x,const point y){ return sqrt(sqr(x.x-y.x)+sqr(x.y-y.y)); }inline double multi(point x,point y,const point z){    x.x-=z.x; x.y-=z.y;    y.x-=z.x; y.y-=z.y;    return x.x*y.y-x.y*y.x;}struct node{int x,y;}a[maxm];inline bool cmp(const node x,const node y){return x.x<y.x;}int vi[maxn],ti;struct seg{double A,B,C,k;point x,y;}line[maxn]; int ln;inline bool cmpl(const seg x,const seg y){    return fabs(x.k-y.k)<eps?multi(y.x,y.y,x.x)<eps:x.k<y.k;}point G(seg x,seg y){    point re;    if(y.B>-eps) swap(x,y);    if(x.B>-eps)    {        re.x=(-x.C)/x.A;        re.y=y.A*re.x+y.C;    }    else    {        re.x=(x.C-y.C)/(y.A-x.A);        if(x.B<-eps) re.y=x.A*re.x+x.C;        else re.y=y.A*re.x+y.C;    }    return re;}void build(const point &x,const point &y){    double A=y.x-x.x,B=y.y-x.y;    if(fabs(A)<eps&&fabs(B)<eps) return;    line[++ln].k=atan2(B,A);    if(fabs(A-0)<eps) line[ln].A=1,line[ln].B=0,line[ln].C=-x.x;    else line[ln].A=B/A,line[ln].B=-1,line[ln].C=x.y-line[ln].A*x.x;    line[ln].x=x; line[ln].y=y;}point t[maxn];seg q[maxn]; int head,tail;int main(){    read(n); read(m);    for(int i=n;i>=1;i--)     {        int x,y; read(x); read(y);        p[i].x=x; p[i].y=y;    }    bool con=true;    for(int i=1;i<=m;i++)    {        int x,y; read(x); read(y);        x=n-x+1; y=n-y+1;        if(x>y) swap(x,y);        if(x==1&&y==n) con=false;        a[i].x=x,a[i].y=y;    }sort(a+1,a+m+1,cmp);    if(con) return printf("%.10lf\n",dis(p[1],p[n])),0;    int now=1; ln=0;    for(int i=1,la=0;i<n;i++)    {        ++ti;        while(now<=m&&a[now].x<=i)        {            if(a[now].x==i) vi[a[now].y]=ti;            now++;        }        int j=n; for(;j>i&&vi[j]==ti;j--);        if(i<j&&j>la) build(p[i],p[j]);        la=max(la,j);    }build(p[n],p[1]);    //sort(line+1,line+ln+1,cmpl);    head=1,tail=0;    for(int i=1;i<=ln;i++)    {        int j=i+1;for(;j<=ln&&fabs(line[i].k-line[j].k)<eps;j++); j--;        i=j;        seg tmp=line[i]; point x=tmp.x,y=tmp.y;        if(head>tail) { q[++tail]=tmp; continue; }        while(head<tail)        {            point z=t[tail-1];            if(multi(x,y,z)<eps) tail--;            else break;        }        while(head<tail)        {            point z=t[head];            if(multi(x,y,z)<eps) head++;            else break;        }        t[tail]=G(q[tail],tmp); q[++tail]=tmp;    }    t[tail]=G(q[tail],q[head]);    double re=dis(t[tail],t[head]);    for(int i=head;i<tail;i++) re+=dis(t[i],t[i+1]);    printf("%.10lf\n",re-dis(p[1],p[n]));    return 0;}
原创粉丝点击