#include<bits/stdc++.h>
#define eps 1e-9
#define ll long long
#define sit set<node> :: iterator
using namespace std;
struct node{
int x,y;
friend node operator +(const node &x,const node &y){
return (node){x.x+y.x,x.y+y.y};
}
friend node operator -(const node &x,const node &y){
return (node){x.x-y.x,x.y-y.y};
}
friend ll operator ^(const node &x,const node &y){
return x.x*y.y-y.x*x.y;
}
friend bool operator ==(const node &x,const node &y){
return fabs(x.x-y.x)<=eps&&fabs(x.y-y.y)<=eps;
}
}o;
ll dis(node x,node y){
return (x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y);
}
bool operator <(node a,node b){
ll tmp=a^b;
if(tmp>0) return 1;
else if(tmp==0&&dis(a,o)<dis(b,o)) return 1;
return 0;
}
set<node> s;
sit pre(sit it){
if(it==s.begin()) it=s.end();
return --it;
}
sit nxt(sit it){
++it;
if(it==s.end()) it=s.begin();
return it;
}
bool query(node x){
sit it=s.lower_bound(x);
if(it==s.end()) it=s.begin();
ll tmp=(x-*pre(it))^(*it-*pre(it));
return tmp<=0;
}
void ins(node x){
if(query(x)) return ;
s.insert(x);
sit it=nxt(s.find(x));
while(s.size()>3&&((x- *(nxt(it)))^(*(it)- *(nxt(it))))<=0) s.erase(it),it=nxt(s.find(x));
it=pre(s.find(x));
while(s.size()>3&&((x-*(it))^(*(it)- *(pre(it))))>=0) s.erase(it);it=pre(s.find(x));
}
int main(){
int q;
scanf("%d",&q);
o=(node){0,0};
for(int i=1;i<=3;i++){
int op;int x,y;
scanf("%d%d%d",&op,&x,&y);
s.insert((node){x,y});
}
q-=3;
while(q--){
int op;int x,y;
scanf("%d%d%d",&op,&x,&y);
if(op==1) ins((node){x,y});
if(op==2){
if(query((node){x,y})) puts("YES");
else puts("NO");
}
}
return 0;
}
以上是我写的一个动态凸包的代码,在样例
5
1 -1 0
1 1 0
1 0 2
2 0 1
2 0 3
将 (1,0) 和 (−1,0) 这两个点当做相同点去掉了,证据在于使用 multiset 问题就解决了,请问这是什么情况