Basic template
一个基础型模板包括一个向量的实现
DATE: 2015-06-01
#define op operator #define __ while #define _0 return typedef long long ll; inline ll _(ll a,ll b){ll t;__(a){t=a;a=b%a;b=t;}_0 b;} struct frac{ ll u,d; frac(ll u=0,ll d=1):u(u),d(d){} frac op()(){ll _1=_(u,d);_0 frac(u/_1,d/_1);} frac op*(frac b){_0 (frac(u*b.u,d*b.d))();} frac op/(frac b){_0 (frac(u*b.d,d*b.u))();} frac op*(ll n){_0 (frac(u*n,d))();} frac op/(ll n){_0 (frac(u,d*n))();} frac op[](ll n){_0 frac(u*n,d*n);} frac op+(ll n){_0 frac(u+d*n,d);} frac op-(ll n){_0 frac(u-d*n,d);} frac op+(frac b){frac _1=(*this)[b.d],_2=b[d];_0 (frac(_1.u+_2.u,_1.d))();} frac op-(frac b){frac _1=(*this)[b.d],_2=b[d];_0 (frac(_1.u-_2.u,_1.d))();} void op=(ll b){d=1,u=b;} ll op()(frac b){return u*b.d-d*b.u;}//<=> bool op==(frac b){return u==b.u&&d==b.d;} bool op>(frac b){return b(*this)<0;} bool op<(frac b){return b(*this)>0;} }; frac op/(ll a,frac b){_0 (frac(b.d*a,b.u))();} frac op-(ll a,frac b){_0 frac(a)-b;} frac op+(ll a,frac b){_0 frac(a)+b;} frac op*(ll a,frac b){_0 (frac(a*b.u,b.d))();} typedef struct vec{ frac x,y; vec(frac x,frac y):x(x),y(y){}; vec op+(vec b){_0 vec(x+b.x,y+b.y);} vec op-(vec b){_0 vec(x-b.x,y-b.y);} vec op*(frac b){_0 vec(x*b,y*b);} vec op/(frac b){_0 vec(x/b,y/b);} vec op*(ll b){_0 vec(x*b,y*b);} vec op/(ll b){_0 vec(x/b,y/b);} frac op*(vec b){_0 x*b.y-y*b.x;}//cross product frac op[](vec b){_0 x*b.x+y*b.y;}//dot product bool op==(vec b){_0 x==b.x&&y==b.y;}//equality test } point;
本模板风格可能引起不适>_<
其实,用'[]'做dot product是因为C++中无法重载'.'运算符,而在大多数动态语言(比如javascript)中'.'与'[]'的作用几乎相等,且在javascript中'.'是一个'[]'的语法糖.
frac里就直接乱凑剩下的符号了>_<
有错误的话请提出来>_<...
Polygon & convex hull
Andrew法凸包.
#include <cstdio> #include <malloc.h> #include <cstring> #include <algorithm> #define op operator #define __ while #define _0 return typedef long long ll; using namespace std; inline ll _(ll a,ll b){ll t;__(a){t=a;a=b%a;b=t;}_0 b;} struct frac{ ll u,d; frac(ll u=0,ll d=1):u(u),d(d){} frac op()(){ll _1=_(u,d);if(d/_1<0)_1=-_1;_0 frac(u/_1,d/_1);} frac op*(frac b){_0 (frac(u*b.u,d*b.d))();} frac op/(frac b){_0 (frac(u*b.d,d*b.u))();} frac op*(ll n){_0 (frac(u*n,d))();} frac op/(ll n){_0 (frac(u,d*n))();} frac op[](ll n){_0 frac(u*n,d*n);} frac op+(ll n){_0 frac(u+d*n,d);} frac op-(ll n){_0 frac(u-d*n,d);} frac op+(frac b){frac _1=(*this)[b.d],_2=b[d];_0 (frac(_1.u+_2.u,_1.d))();} frac op+(frac b){frac _1=(*this)[b.d],_2=b[d];_0 (frac(_1.u-_2.u,_1.d))();} void op=(ll b){d=1,u=b;} ll op()(frac b){return u*b.d-d*b.u;}//<=> bool op==(frac b){return u==b.u&&d==b.d;} } frac op/(ll a,frac b){_0 (frac(b.d*a,b.u))();} frac op-(ll a,frac b){_0 frac(a)-b;} frac op+(ll a,frac b){_0 frac(a)+b;} frac op*(ll a,frac b){_0 (frac(a*b.u,b.d))();} typedef struct vec{ frac x,y; vec(frac x,frac y):x(x),y(y){}; vec op+(vec b){_0 vec(x+b.x,y+b.y);} vec op-(vec b){_0 vec(x-b.x,y-b.y);} vec op*(frac b){_0 vec(x*b,y*b);} vec op/(frac b){_0 vec(x/b,y/b);} vec op*(ll a){_0 vec(x*b,y*b);} vec op/(ll b){_0 vec(x/b,y/b);} frac op*(vec b){_0 x*b.y-y*b.x;}//cross product frac op[](vec b){_0 x*b.x+y*b.y;}//dot product bool op==(vec b){_0 x==b.x&&y==b.y;}//equality test } point; bool pcmp(const point& p1,const point& p2){ ll a=p1.x(p2.x); if(a>0) return false; if(a<0) return true; return p1.y(p2.y)<0; } struct polygon{ point* p; int n,s; polygon(int k,point* q){ s=(n=k)<<1; p=(point*)malloc(s*sizeof(point)); for(int i=0;i<n;++i) p[i]=q[i]; } inline void sizeup(int q){ s<<=1; if(s>q){ free(p); p=(point*)malloc(s*sizeof(point)); } } inline void copy(polygon a){ while(a.n>s){ sizeup(a.n); } n=a.n; for(int i=0;i<n;++i) p[i]=a.p[i]; } void op=(polygon a){ copy(a); } void op=(polygon* a){ copy(*a); } frac area(){ frac area(0,1); for(int i=1;i<n-1;++i) area+=(p[i]-p[0])*(p[i+1]-p[0]); return area/2; } void sort(){ sort(p,p+n,pcmp); } } struct convex_hull{ polygon pol;//convex hull is also a polygon convex_hull(polygon* x){ pol=x; polygon pol2=x; pol2.sort(); int m=0; for(int i=0;i<pol2.n;++i){ while(m>1 && ((pol.p[m-1]-pol.p[m-2])*(pol2.p[i]-pol.p[m-2]))(frac(0,1))<0ll) m--; pol.p[m++]=pol2.p[i]; } int k=m; for(int i=pol2.n-2;~i;--){ while(m>1 && ((pol.p[m-1]-pol.p[m-2])*(pol2.p[i]-pol.p[m-2]))(frac(0,1))<0ll) m--; pol.p[m++]=pol2.p[i]; } if(pol2.n>1) m--; pol.n=m; } } int main(){ return 0; }
直接convex_hull(polygon)就求好凸包了>_<
凸包就是一个多边形嘛,就是凸的>_<