题目链接https://codeforces.com/contest/70/problem/D
题意
有两种操作:
- 平面上添加一个点
- 询问一个点,是否在已添加点形成的凸包内
题解
用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");
}
}
来源:https://blog.csdn.net/monochrome00/article/details/100540269