又看了眼宽爷的ppt。
发现还是一个题都不会
看到这个动态凸包蛮好玩的。(然后写了一年)
我们维护两个凸壳,存的点。
每次插入看看x坐标所在的位置,然后向两边不停的判叉积就行了。。。我写的好像比较丑(
#include <bits/stdc++.h>
#define fi first
#define se second
#define mp map<db,db>
using namespace std;
typedef long long db;
struct point {
db x, y;
point operator+(const point &k1) const { return (point) {k1.x + x, k1.y + y}; }
point operator-(const point &k1) const { return (point) {x - k1.x, y - k1.y}; }
point operator*(db k1) const { return (point) {x * k1, y * k1}; }
point operator/(db k1) const { return (point) {x / k1, y / k1}; }
int operator==(const point &k1) const { return x==k1.x&& y==k1.y; }
};
db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;}
mp up,down;
bool check(mp &p,int x,int y){
if(p.empty())return 0;
if(x<p.begin()->first||x>p.rbegin()->first)return 0;
auto pr = p.lower_bound(x),nt=pr--;
if(nt->first==x)return nt->second>=y;
return cross(point{x,y}-point{pr->first,pr->second},point{nt->first,nt->second}-point{pr->first,pr->second})>=0;
}
void insert(mp &p,int x,int y){
if(check(p,x,y))return;
mp::iterator it,a,b;
p[x]=y;
it=p.lower_bound(x);
b=it;++b;
if(b!=p.end()){
a=b++;
while (b!=p.end()&&cross((point){a->fi,a->se}-(point){it->fi,it->se},(point){b->fi,b->se}-(point){it->fi,it->se})>=0)p.erase(a),a=b++;
}
a=it;--a;
if(it!=p.begin()&&a!=p.begin()){
b=a--;
while(b!=p.begin()&&cross((point){b->fi,b->se}-(point){it->fi,it->se},(point){a->fi,a->se}-(point){it->fi,it->se})<=0)p.erase(b),b=a--;
}
}
int q,t,x,y;
int main(){
scanf("%d",&q);
while (q--){
scanf("%d%d%d",&t,&x,&y);
if(t==1){
insert(up,x,y);
insert(down,x,-y);
}else{
puts((check(up,x,y)&&check(down,x,-y))?"YES":"NO");
}
}
}