It was still a mutter I N long stuff
Minkowski and is a strange thing
He was a long way
$S={a+b | a \bel A , b \bel B}$
AB point may be set, but also vector set (apparently)
He can deal with some strange things
For instance, we look at this problem
It is to determine whether you find the vector AB is present in the Minkowski and in its requirements
Then you put on the board finished it
Well, you probably understand what Minkowski and
We now learn how to write
The point on we intuitively understood Minkowski certain point on the convex hull of the set of points constituting
So we find all points of violence once again seek to finish the convex hull complexity is O (| A | * | B |)
It looks not very gifted certainly can be optimized
We found a good spot on the nature of its convex hull slope is monotonic it is clear that the optimization can be TwoPointers
We direct observation which expand on it outside
Code implements throw here
//Love and Freedom. #include<algorithm> #include<cmath> #include<cstring> #include<cstdio> #define inf 20021225 #define ll long long #define db double #define eps 1e-8 #define N 200010 using namespace std; int read() { int f=1,s=0; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return f*s; } struct then { db x,y; then(){} poi(db _x,db _y){x=_x,y=_y;} }; typedef then vec; Case operator + (a case, case b) { return object (A.x + bx, a.y + b.y);} Case operator - (a case, case b) { return Case (ax-bx, AY by);} Case operator * (case a, b db) { return object (ax + b, y * p);} Case operator / (case a, b db) { return Case (x / b, and y / b);} db cross(vec a,vec b){return a.x*b.y-a.y*b.x;} db dot(vec a){return a.x*a.x+a.y*a.y;} db only (case a) { return sqrt (dot (a));} db dis (then a, then b) { return len (b- a);} then p0; int dcmp(db x){return x>eps?1:x<-eps?-1:0;} bool cmp(poi p1,poi p2){return dcmp(cross(p1-p0,p2-p0))==1||(dcmp(cross(p1-p0,p2-p0))==0&&dis(p0,p1)<dis(p0,p2));} int gethull(poi *p,poi *h,int n) { p0=poi{1e18,1e18}; int id=0; for(int i=1;i<=n;i++) if(dcmp(p[i].x-p0.x)<0||(dcmp(p[i].x-p0.x)==0&&dcmp(p[i].y-p0.y)<0)) id=i,p0=p[i]; swap(p[1],p[id]); sort(p+2,p+n+1,cmp); int top=2; h[1]=p[1],h[2]=p[2]; for(int i=3;i<=n;i++) { while(top>2&&dcmp(cross(p[i]-h[top-1],h[top]-h[top-1]))>=0) top--; h[++top]=p[i]; } return top; } poi A[N],B[N],p[N],C[N]; int na,nb,nc; void minkowski() { A [ 1 ] = A [ 1 ], B [NB + 1 ] = B [ 1 ]; C[nc=1]=A[1]+B[1]; int i=1,j=1; while(i<=na&&j<=nb) { vec v1=A[i+1]+B[j]-C[nc],v2=A[i]+B[j+1]-C[nc]; if(dcmp(cross(v1,v2))>=0) C[++nc]=A[i+1]+B[j],i++; else C[++nc]=A[i]+B[j+1],j++; } while(i<=na) C[++nc]=A[i]+B[j],i++; while(j<=nb) C[++nc]=A[i]+B[j],j++; } bool check (then w) { if((dcmp(cross(w-C[1],C[nc]-C[1]))==0&&dis(C[nc],C[1])>=dis(C[1],w))||(dcmp(cross(w-C[1],C[2]-C[1]))==0 && dis(C[1],w)<=dis(C[2],C[1]))) return 1; int l=2,r=nc,ans=0; while(l<=r) { int mid=l+r>>1; poi p1=C[mid]; if(dcmp(cross(p1-C[1],w-C[1]))>=0) l=mid+1,ans=mid; else r=mid-1; } if (n == || years years!) return 0 ; poi p1=C[ans],p2=C[ans+1]; if(dcmp(cross(p1-w,p2-w))>=0) return 1; return 0; } int main () { int n1=read(),n2=read(),q=read(); for(int i=1;i<=n1;i++) p[i].x=read(),p[i].y=read(); na=gethull(p,A,n1); for(int i=1;i<=n2;i++) p[i].x=-read(),p[i].y=-read(); nb=gethull(p,B,n2); minkowski(); while(q--) { poi w; w.x=read(),w.y=read(); printf("%d\n",check(w)); } return 0; }
Note: 1 point if you can find direct triangulation points in the next two polar angle range within which you can 2. As to why I would like to hammer my own dog's head explode it because I cmp wrote dcmp> 1 tune in the convex hull a century xtbl
Another questions
N school entrance exam questions
(Title face could not seem to put / px)
Our first guess is concluded for odd and even answers are convex, so consider maintaining the parity of four convex positive and negative answers
We do consider how to merge partition
Because the difference is convex so monotonous that we can optimize TwoPointers
Then find complete answers continue to maintain a differential array
(This stuff seemingly also called the partition max convolution / px)
This discovery process is actually in demand and Minkowski
My code is written in discussions so long it really fast, but a thief (
//Love and Freedom. #include<algorithm> #include<cmath> #include<cstring> #include<cstdio> #define inf (ll)(1e18) #define ll long long #define N 500010 using namespace std; int read() { int f=1,s=0; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return f*s; } ll f[N][2],d[N][2],tmp[N][2],a[N]; void solve(int l,int r) { if(l==r){f[l][0]=a[l],f[l][1]=a[l]; d[l][0]=a[l],d[l][1]=a[l]; return;} int mid=l+r>>1; solve(l,mid); solve(mid+1,r); int it1,it2; ll val; for(int i=0;i<=r-l+1;i++) tmp[i][0]=-inf,tmp[i][1]=inf; it1=l+1,it2=mid+1; val=d[l][0]; for(int i=1;i<=r-l+1;i+=2) // odd l odd+ r even- { tmp[i][0]=max(tmp[i][0],val); if(it2>r-1 && it1>mid-1) break; if(it2>r-1 || (it1<=mid-1&&d[it1][0]+d[it1+1][0]>-d[it2][1]-d[it2+1][1])) val+=d[it1][0]+d[it1+1][0],it1+=2; else val-=d[it2][1]+d[it2+1][1],it2+=2; } it1=l,it2=mid+2,val=d[mid+1][0];// printf("%lld\n",val); for(int i=1;i<=r-l+1;i+=2) // odd l even+ r odd+ { tmp[i][0]=max(tmp[i][0],val); if(it2>r-1 && it1>mid-1) break; if(it2>r-1 || (it1<=mid-1&&d[it1][0]+d[it1+1][0]>d[it2][0]+d[it2+1][0])) val+=d[it1][0]+d[it1+1][0],it1+=2; else val+=d[it2][0]+d[it2+1][0],it2+=2; } it1=l+1,it2=mid+2,val=d[l][0]-d[mid+1][1]; for(int i=2;i<=r-l+1;i+=2) // even l odd+ r odd- { tmp[i][0]=max(tmp[i][0],val);//printf("%d %d %d %lld\n",i,it1,it2,val);// printf("%lld\n",val); if(it2>r-1 && it1>mid-1) break; if(it2>r-1 || (it1<=mid-1&&d[it1][0]+d[it1+1][0]>-d[it2][1]-d[it2+1][1])) val+=d[it1][0]+d[it1+1][0],it1+=2; else val-=d[it2][1]+d[it2+1][1],it2+=2; } it1=l,it2=mid+1,val=0; for(int i=0;i<=r-l+1;i+=2) // even l even+ r even+ { tmp[i][0]=max(tmp[i][0],val); if(it2>r-1 && it1>mid-1) break; if(it2>r-1 || (it1<=mid-1&&d[it1][0]+d[it1+1][0]>d[it2][0]+d[it2+1][0])) val+=d[it1][0]+d[it1+1][0],it1+=2; else val+=d[it2][0]+d[it2+1][0],it2+=2; } it1=l+1,it2=mid+1; val=d[l][1]; for(int i=1;i<=r-l+1;i+=2) // odd l odd+ r even- { tmp[i][1]=min(tmp[i][1],val); if(it2>r-1 && it1>mid-1) break; if(it2>r-1 || (it1<=mid-1&&d[it1][1]+d[it1+1][1]<-d[it2][0]-d[it2+1][0])) val+=d[it1][1]+d[it1+1][1],it1+=2; else val-=d[it2][0]+d[it2+1][0],it2+=2; } it1=l,it2=mid+2,val=d[mid+1][1]; for(int i=1;i<=r-l+1;i+=2) // odd l even+ r odd+ { tmp[i][1]=min(tmp[i][1],val); if(it2>r-1 && it1>mid-1) break; if(it2>r-1 || (it1<=mid-1&&d[it1][1]+d[it1+1][1]<d[it2][1]+d[it2+1][1])) val+=d[it1][1]+d[it1+1][1],it1+=2; else val+=d[it2][1]+d[it2+1][1],it2+=2; } it1=l+1,it2=mid+2,val=d[l][1]-d[mid+1][0]; for(int i=2;i<=r-l+1;i+=2) // even l odd+ r odd- { tmp[i][1]=min(tmp[i][1],val); if(it2>r-1 && it1>mid-1) break; if(it2>r-1 || (it1<=mid-1&&d[it1][1]+d[it1+1][1]<-d[it2][0]-d[it2+1][0])) val+=d[it1][1]+d[it1+1][1],it1+=2; else val-=d[it2][0]+d[it2+1][0],it2+=2; } it1=l,it2=mid+1,val=0; for(int i=0;i<=r-l+1;i+=2) // even l even+ r even+ { tmp[i][1]=min(tmp[i][1],val); if(it2>r-1 && it1>mid-1) break; if(it2>r-1 || (it1<=mid-1&&d[it1][1]+d[it1+1][1]<d[it2][1]+d[it2+1][1])) val+=d[it1][1]+d[it1+1][1],it1+=2; else val+=d[it2][1]+d[it2+1][1],it2+=2; } //printf("%d %d\n",l,r); for(int i=1;i<=r-l+1;i++) f[l+i-1][0]=tmp[i][0], f[l+i-1][1]=tmp[i][1]; //puts(""); d[l][0]=f[l][0],d[l][1]=f[l][1]; for(int i=l+1;i<=r;i++) d[i][0]=f[i][0]-f[i-1][0], d[i][1]=f[i][1]-f[i-1][1]; } int main () { int n=read(); for(int i=1;i<=n;i++) a[i]=read(); solve(1,n); for(int i=1;i<=n;i++) printf("%lld ",f[i][0]); return 0; }