【动态凸包】Codeforces - 70 - D - Professor's task

拥有回忆 提交于 2019-11-29 06:31:57

题目链接https://codeforces.com/contest/70/problem/D


题意

有两种操作:

  1. 平面上添加一个点
  2. 询问一个点,是否在已添加点形成的凸包内

题解

用set维护上凸包和下图包维护即可,
主要是一些细节的处理比较麻烦,
然后代码一定要优雅。。。


#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<time.h>
#include<set>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> piir;
struct Point{
    ll x,y;
    bool operator<(const Point k)const{
        if(x==k.x) return y>k.y;
        return x<k.x;
    }
    Point operator - (const Point k)const{return (Point){x-k.x,y-k.y};}
    bool operator==(const Point k)const{return x==k.x&&y==k.y;}
    void input(){scanf("%lld%lld",&x,&y);}
    void output(){printf("(%lld,%lld)\n",x,y);}
};
db cross(Point k1,Point k2){return k1.x*k2.y-k2.x*k1.y;}
set<Point>up,dw;
bool check(set<Point>&st,Point p){
    if(st.size()<=1) return false;
    auto it=st.lower_bound(p);
    if(it==st.begin()){
        if((*it).x==p.x&&((*it).y>=p.y)) return true;
        return false;
    }
    if(it==st.end()){
        it--;
        if((*it).x==p.x&&((*it).y>=p.y)) return true;
        else return false;
    }
    auto jt=it;jt--;
    if(cross(p-(*jt),(*it)-(*jt))>=0) return true;
    return false;
}
void dele_ri(set<Point>&st,Point p){
    auto it=st.lower_bound(p);
    if(it==st.end()) return;
    auto jt=it;jt++;
    while(jt!=st.end()){
        if(cross(p-(*jt),(*it)-(*jt))>0){
            st.erase(it);
            it=jt;jt++;
        }
        else return;
    }
    if((*it).x==p.x&&(*it).y<p.y) st.erase(it);
}
void dele_le(set<Point>&st,Point p){
    auto it=st.lower_bound(p);
    if(it==st.begin()) return;it--;
    auto jt=it;
    if(jt==st.begin()) return;jt--;
    while(it!=st.begin()){
        if(cross(p-(*jt),(*it)-(*jt))<0){
            st.erase(it);
            it=jt;jt--;
        }
        else return;
    }
    if((*it).x==p.x&&(*it).y<p.y) st.erase(it);
}
void solve(set<Point>&st,Point p){
    if(check(st,p)) return;
    dele_ri(st,p);
    dele_le(st,p);
    st.insert(p);
}
int main()
{
    //freopen("in.in","r",stdin);
    int n,o;
    ll x,y;
    scanf("%d",&n);
    up.clear();dw.clear();
    for(int i=1;i<=n;i++){
        scanf("%d%lld%lld",&o,&x,&y);
        if(o==1){
            solve(dw,(Point){x,-y});
            solve(up,(Point){x,y});
        }
        else{
            if(check(up,(Point){x,y})&&check(dw,(Point){x,-y})) printf("YES\n");
            else printf("NO\n");
        }
        //printf("up: ");for(auto it:up) printf("(%lld,%lld) ",it.x,it.y);printf("\n");
        //printf("dw: ");for(auto it:dw) printf("(%lld,%lld) ",it.x,it.y);printf("\n");
    }
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!