zoukankan      html  css  js  c++  java
  • bzoj 1249: SGU277 HERO

    题意

    这是极角序维护凸包。

    找一个点作为基准点,我选的是(p1)(p_2,p_3)的中点的中点。

    (set)维护凸包,内部按照极角排序。

    插入一个点:
    如果之前存在就不插入。
    不然就找到它的前驱(pre)和后继(nxt),之后不断弹掉两边的点,中途维护下面积即可。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=100010;
    const double eps=1e-8;
    int n,cnt=3;
    ll ans;
    struct Point
    {
        double x,y;
        inline double len(){return x*x+y*y;}
        Point operator+(const Point& a)const{return (Point){x+a.x,y+a.y};}
        Point operator-(const Point& a)const{return (Point){x-a.x,y-a.y};}
        Point operator*(const double& k){return (Point){x*k,y*k};}
        Point operator/(const double& k){return (Point){x/k,y/k};}
        double operator*(const Point& a)const{return x*a.y-y*a.x;}
        double operator&(const Point& a)const{return x*a.x+y*a.y;}
    };
    Point st;
    Point p[5];
    inline int dcmp(double x)
    {
        if(fabs(x)<=eps)return 0;
        return x<0?-1:1;
    }
    bool operator<(Point a,Point b)
    {
        Point tmpa=a-st,tmpb=b-st;
        if(dcmp(tmpa.y*tmpb.y)<0)return dcmp(tmpa.y-tmpb.y)<0;
        if(!dcmp(tmpa.y)&&!dcmp(tmpb.y)&&dcmp(tmpa.x*tmpb.x)<0)return dcmp(tmpa.x-tmpb.x)<0;
        double det=tmpa*tmpb;
        if(dcmp(det)!=-0)return dcmp(det)>0;
        return dcmp(a.len()-b.len())>0;
    }
    set<Point>s;
    inline Point getpre(Point a)
    {
        set<Point>::iterator it=s.find(a);
        if(it==s.begin())it=s.end();
        return *(--it);
    }
    inline Point getnxt(Point a)
    {
        set<Point>::iterator it=s.find(a);
        if((++it)==s.end())it=s.begin();
        return *it;
    } 
    inline ll calc(Point a,Point b)
    {
        a=a-p[1],b=b-p[1];
        return abs((ll)a.x*(ll)b.y-(ll)a.y*(ll)b.x);
    }
    int main()
    {
        //freopen("test.in","r",stdin);
        //freopen("test.out","w",stdout);
        for(int i=1;i<=3;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
        st=(p[1]+(p[2]+p[3])*0.5)*0.5;
        ans=calc(p[2],p[3]);
        for(int i=1;i<=3;i++)s.insert(p[i]);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            Point a;scanf("%lf%lf",&a.x,&a.y);
            if(s.count(a)){printf("%lld
    ",ans);continue;}
            s.insert(a);
            Point pre=getpre(a),nxt=getnxt(a);
            if(dcmp((a-pre)*(nxt-a))<0)
            {
                s.erase(a);
                printf("%lld
    ",ans);
                continue;
            }
            cnt++;
            ans-=calc(pre,nxt);
            Point b=getpre(pre);
            while(cnt>3&&dcmp((pre-b)*(a-pre))<=0)
            {
                ans-=calc(b,pre);
                s.erase(pre);cnt--;
                pre=b,b=getpre(pre);
            }
            b=getnxt(nxt);
            while(cnt>3&&dcmp((nxt-a)*(b-nxt))<=0)
            {
                ans-=calc(nxt,b);
                s.erase(nxt);cnt--;
                nxt=b,b=getnxt(nxt);
            }
            ans+=calc(pre,a)+calc(a,nxt);
            printf("%lld
    ",ans);
        }
        return 0;
    } 
    
  • 相关阅读:
    Grakn Forces 2020 I. Bitwise Magic
    October Challenge 2020 Division 1
    杂题
    杂题
    杂题
    hdu 6868
    Codeforces Round #673 (Div. 1)
    杂题
    2019 ICPC World Finals K
    【CSP2019】括号树 题解(递推+链表)
  • 原文地址:https://www.cnblogs.com/nofind/p/12172505.html
Copyright © 2011-2022 走看看