Codeforces 70D 动态凸包(极角排序)

View Code
#include<iostream>
#include<cstdio>
#include<set>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
struct point{ll x,y,d;double z;}a[5],s,p;
typedef set<point>::iterator setp;
int n,i,j;
set<point> f;
setp it,it1,it2;

ll cross(point a,point b,point c)
{
    return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}

bool operator <(point a,point b)
{
    return a.z+1e-10<b.z||fabs(a.z-b.z)<1e-10&&a.d<b.d;
}

inline setp l(setp it)
{
    setp ret=it;
    if(ret==f.begin()) ret=--f.end(); else --ret;
    return ret;
}


inline setp r(setp it)
{
    setp ret=it;
    if(ret==--f.end()) ret=f.begin(); else ++ret;
    return ret;
}

int main()
{
    cin>>n;
    for(i=1;i<=3;i++)
    {
        cin>>j>>a[i].x>>a[i].y;
        s.x+=a[i].x,s.y+=a[i].y;
        a[i].x*=3,a[i].y*=3;
    }
    if(cross(s,a[1],a[2])<0) swap(a[1],a[3]);
    for(i=1;i<=3;i++)
    {
        a[i].z=atan2(a[i].y-s.y,a[i].x-s.x);
        a[i].d=(a[i].x-s.x)*(a[i].x*s.x)+(a[i].y-s.y)*(a[i].y*s.y);
    }
    f.insert(a+1,a+4);
    for(i=4;i<=n;i++)
    {
        scanf("%d%I64d%I64d",&j,&p.x,&p.y);
        p.x*=3,p.y*=3,p.z=atan2(p.y-s.y,p.x-s.x);
        p.d=(p.x-s.x)*(p.x-s.x)+(p.y-s.y)*(p.y-s.y);
        it=f.lower_bound(p);
        if(it==f.end()) it=f.begin();
        it1=l(it);
        if(cross(*it1,p,*it)<=0) {if(j==2) puts("YES"); continue;}
        if(j==2) {puts("NO"); continue;}


        f.insert(p);
        it=f.find(p);
        it1=l(it); it2=l(it1);
        while(cross(*it2,*it1,*it)<0)
        {
            f.erase(it1);
            it1=it2; it2=l(it1);
        }
        it1=r(it); it2=r(it1);
        while(cross(*it,*it1,*it2)<0)
        {
            f.erase(it1);
            it1=it2; it2=r(it1);
        }
    }
    return 0;
}

 

posted @ 2013-01-17 22:31  To be an ACMan  Views(354)  Comments(0)    收藏  举报