70D

来源:互联网 发布:手机php电视直播源码 编辑:程序博客网 时间:2024/04/29 16:17
动态凸包板子题。只要分成上凸壳和下凸壳分别处理就好了。先二分看该点位于哪两点间,在根据它与直线的位置关系判断。
本来想自己敲的,可我写了5K,调了一天没搞出来。拉标程对拍时发现他只写了1K,mmp。
而且写得很好理解。所以我就抄了一发。。。
这个故事告诉我们在适当的时候要学会膜标程。
附:标程blog:http://blog.csdn.net/crazy_ac/article/details/8499443
你会发现两个代码几乎完全一样。
#include<cstdio>#include<cstring>#include<iostream>#include<vector>#include<algorithm>#include<map>#include<cmath>#include<queue>using namespace std;#define rep(i,j,k) for(i=j;i<=k;++i)#define per(i,j,k) for(i=j;i>=k;--i)#define sqr(x) ((x)*(x))#define G getchar()#define LL long long#define pii pair<int,int>#define mkp make_pair#define X first#define Y second#define N 100005#define inf 1000001.0#define eps 0.000001map<int,int>mp1,mp2;void write(map<int,int>&mp){map<int,int>::iterator ii;for(ii=mp.begin();ii!=mp.end();++ii){printf("%d %d\n",ii->X,ii->Y);}puts("");}pii operator -(pii x,pii y){return mkp(x.X-y.X,x.Y-y.Y);}LL Cross(pii x,pii y){return (LL)x.X*y.Y-(LL)x.Y*y.X;}bool judge(pii x,pii y,pii z){return Cross(y-x,z-y)<=0;}bool check(map<int,int>&mp,int x,int y){if(mp.empty())return false;if(mp.find(x)!=mp.end())return y>=mp[x];if(x<mp.begin()->X||x>(--mp.end())->X)return false;map<int,int>::iterator ii,jj;ii=mp.lower_bound(x);jj=ii--;return judge(*ii,mkp(x,y),*jj);}void ins(map<int,int>&mp,int x,int y){if(check(mp,x,y))return;mp[x]=y;map<int,int>::iterator ii,jj;ii=mp.upper_bound(x);pii tmp=mkp(x,y);if(ii!=mp.end()){while(1){jj=ii++;if(ii==mp.end()||!judge(tmp,*jj,*ii))break;mp.erase(jj);}}ii=mp.find(x);if(ii==mp.begin())return;if(--ii==mp.begin())return;do{jj=ii--;if(!judge(*ii,*jj,tmp))break;mp.erase(jj);}while(ii!=mp.begin());}int main(){int Q,o,x,y;scanf("%d",&Q);while(Q--){scanf("%d%d%d",&o,&x,&y);if(o==1)ins(mp1,x,y),ins(mp2,x,-y);else puts(check(mp1,x,y)&&check(mp2,x,-y)?"YES":"NO");}return 0;}

原创粉丝点击