Codeforces gym 100517 (two points, same direction judgment)

Question: a convex bag is provided, which is given in clockwise order. The number of points cannot exceed 0.1 million. Two different points are given. The points are strictly in the convex bag. The convex bag ensures that no three points are collocated, the number of vertices (pi, pj) on the convex hull satisfies the requirement that the line segments of pi and pj strictly interwork with the line segments of the two points. The strict intersection between the line segments means that the intersection is not at the endpoint.

Link: http://codeforces.com/gym/100517)

Solution: If a convex Packet Has n points, the p of the convex packet point set is doubled to 2n points. The first n vertices of the enumeration, which are enumerated to I each time, are divided into two vertices in [I + 1, I + n-1], and the two vertices p1, p2, the point where p1 and p2 are the "closest" line segments. Count the intermediate number. During the bipartite process, you need to make a judgment in the same direction, that is, to determine whether the straight line is in the "Left" or "right" of a line segment, and use the cross product to determine.

Code

```
//Hello. I'm Peter.//#pragma comment(linker, /STACK:102400000,102400000)#include
#include
#include
#include
#include
#include
#include
#include#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long ll;inline int read(){ int x=0,f=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}const double eps = 1e-9, pi = acos(-1.0);inline int sgn(double x){ if(fabs(x) < eps) return 0; else return x > 0? 1 : -1;}struct Point{ double x, y; Point(){}; Point(double x1, double y1){x = x1, y = y1;}};typedef Point Vector;Vector operator + (const Vector a, const Vector b){return Vector(a.x + b.x, a.y + b.y);}Vector operator - (const Vector a, const Vector b){return Vector(a.x - b.x, a.y - b.y);}double operator * (const Vector a, const Vector b){return a.x * b.x + a.y * b.y;}double operator % (const Vector a, const Vector b){return a.x * b.y - a.y * b.x;}Vector operator * (const Vector a, const double b){return Vector(a.x * b, a.y * b);}Vector operator * (const double b, const Vector a){return Vector(a.x * b, a.y * b);}Vector operator / (const Vector a, const double b){return Vector(a.x / b, a.y / b);}bool operator == (const Point a, const Point b){return sgn(a.x - b.x)==0 && sgn(a.y - b.y)==0;}bool operator || (const Vector a, const Vector b){return sgn(a % b)==0;}bool operator / (const Vector a, const Vector b){return sgn(a % b)!=0;}double Length(Vector v){return (double)sqrt((double)(v.x * v.x + v.y * v.y));}double Dis(Point a, Point b){return Length(a - b);}Vector Rotate(Vector v, double rad){return Vector(v.x * cos(rad) - v.y * sin(rad), v.x * sin(rad) + v.y * cos(rad));}double angle(Vector v){return atan2(v.y, v.x);}double angle(Vector a, Vector b){ double ans = angle(a) - angle(b); while(sgn(ans) < 0) ans += 2*pi; while(sgn(ans) >= 2*pi) ans -= 2*pi; return fmin(ans, 2*pi - ans);}double Area_Tri(Point p1, Point p2, Point p3){return 0.5 * fabs((p2 - p1) % (p3 - p1));}double Area_Tri(double a, double b, double c){double p = (a+b+c)/2; return (double)sqrt((double)(p*(p-a)*(p-b)*(p-c)));}struct Line{ Point p; Vector v; Line(){}; Line(Point p1, Vector v1){p = p1, v = v1;}};Point operator / (const Line a, const Line b){ double t = ((b.p - a.p) % b.v) / (a.v % b.v); return a.p + a.v * t;}double Dis(Point p, Line l){return fabs(l.v % (p - l.p)) / Length(l.v);}double angle(Line a, Line b){double ans = angle(a.v, b.v); return fmin(ans, pi - ans);}struct Seg{ Point p1, p2; Seg(){}; Seg(Point p11, Point p22){p1 = p11, p2 = p22;}};bool operator / (const Seg a, const Seg b){//need change return sgn((a.p2 - a.p1) % (b.p1 - a.p1)) * sgn((a.p2 - a.p1) % (b.p2 - a.p1)) <= 0 && sgn((b.p2 - b.p1) % (a.p1 - b.p1)) * sgn((b.p2 - b.p1) % (a.p2 - b.p1)) <= 0 ;}bool operator / (const Line a, const Seg b){ return sgn(a.v % (b.p1 - a.p)) * sgn(a.v % (b.p2 - a.p)) <= 0;}bool PointOnSeg(Point p, Seg s){ if((s.p1 - p) / (s.p2 - p)) return false; else if(sgn((s.p1 - p) * (s.p2 - p)) > 0) return false; else return true;}#define N 200010int n;Point p[N];Point p1 , p2;Point readPoi(){ int x, y; x = read(), y = read(); return Point(x, y);}void kuoda(){ for(int i = n + 1; i <= n + n; i++){ p[i] = p[i - n]; }}void solve(){ ll ans = 0; for(int i = 1; i <= n; i++){ int l ,r , mid; l = i + 1, r = i + n - 1; Vector v1 = p1 - p[i], v2 = p2 - p[i]; while(l < r){ mid = (l + r) >> 1; Vector v = p[mid] - p[i]; if(sgn(v % v1) <= 0 && sgn(v % v2) <= 0) r = mid; else l = mid + 1; } int tp1 = l; l = i + 1, r = i + n - 1; while(l < r){ mid = (l + r) >> 1; mid++; Vector v = p[mid] - p[i]; if(sgn(v % v1) >= 0 && sgn(v % v2) >= 0) l = mid; else r = mid - 1; } int tp2 = l; if(tp1 != tp2) ans += tp1 - tp2 - 1; } ans >>= 1; cout< 0){ for(int i = 1; i <= n; i++) p[i] = readPoi(); p1 = readPoi(); p2 = readPoi(); kuoda(); solve(); } return 0;}
```