Test instructions: Gave a convex bag, in a clockwise order to point, points not more than 100,000, and gave two different points, point strictly in the convex hull, convex package to ensure that there is no three-point collinear, ask how many points on the convex Hull (pi, PJ), to meet the Pi and PJ line segments with two points of the line strictly intersect, A strict intersection between segments means that the intersection is not at the endpoint.
Links: http://codeforces.com/gym/100517 (question K)
Solution: The convex hull has n points, the convex hull point set P is enlarged one times and becomes 2n points. Enumeration of the first n points, each enumeration to I, in [I+1, I+n-1] for two points, found two points p1,p2, meet P1 and P2 is "closest" to the point of the two-point segment. Statistics of the middle number can be. In the two-part process, it is necessary to make a judgment of the same direction, that is to judge whether the line is in a segment "left" or "right", and can be judged by cross product.
Code
//hello. I ' m Peter.//#pragma comment (linker, "/stack:102400000,102400000")#include <cstdio>#include <iostream>#include <sstream>#include <cstring>#include <string>#include <cmath>#include <cstdlib>#include <algorithm>#include <functional>#include <cctype>#include <ctime>#include <stack>#include <queue>#include <vector>#include <set>#include <map>using namespace STD;typedef Long Longllinline intRead () {intx=0, f=1;CharCh=getchar (); while(ch>' 9 '|| ch<' 0 '){if(ch=='-') f=-1; Ch=getchar ();} while(ch>=' 0 '&&ch<=' 9 ') {x=x*Ten+ch-' 0 '; Ch=getchar ();}returnX*f;}Const DoubleEPS =1e-9, pi =ACOs(-1.0);inline intSgnDoublex) {if(fabs(x) < EPS)return 0;Else returnX >0?1: -1;}structpoint{Doublex, y; Point () {}; Point (DoubleX1,Doubley1) {x = x1, y = y1;}};typedefPoint Vector; Vectoroperator+ (ConstVector A,ConstVector b) {returnVector (a.x + b.x, A.Y + b.y);} Vectoroperator- (ConstVector A,ConstVector b) {returnVector (a.x-b.x, a.y-b.y);}Double operator* (ConstVector A,ConstVector b) {returna.x * b.x + a.y * B.Y;}Double operator% (ConstVector A,ConstVector b) {returna.x * B.Y-A.Y * b.x;} Vectoroperator* (ConstVector A,Const Doubleb) {returnVector (a.x * b, a.y * b);} Vectoroperator* (Const DoubleBConstVector a) {returnVector (a.x * b, a.y * b);} Vectoroperator/ (ConstVector A,Const Doubleb) {returnVector (a.x/b, a.y/b);}BOOL operator== (ConstPoint A,ConstPoint B) {returnSGN (a.x-b.x) = =0&& sgn (a.y-b.y) = =0;}BOOL operator|| (ConstVector A,ConstVector b) {returnSGN (a% b) = =0;}BOOL operator/ (ConstVector A,ConstVector b) {returnSGN (a% b)! =0;}DoubleLength (Vector v) {return(Double)sqrt((Double) (v.x * v.x + v.y * v.y));}DoubleDis (Point A, point B) {returnLength (A-B);} Vector Rotate (vector v,Doublerad) {returnVector (v.x *Cos(RAD)-V.y *Sin(RAD), v.x *Sin(RAD) + V.y *Cos(RAD));}DoubleAngle (Vector v) {return atan2(V.y, v.x);}DoubleAngle (vector A, vector b) {DoubleAns = angle (a)-angle (b); while(SGN (ANS) <0) ans + =2*pi; while(SGN (ANS) >=2*PI) ans-=2*pi;returnFmin (ans,2*pi-ans);}DoubleArea_tri (Point P1, point P2, point p3) {return 0.5*fabs((P2-P1)% (P3-P1));}DoubleArea_tri (DoubleADoubleBDoublec) {Doublep = (a+b+c)/2;return(Double)sqrt((Double) (p* (p-a) * (p-b) * (P-C)));}structline{point P; Vector v; Line () {}; Line (Point P1, Vector v1) {p = p1, v = v1;}}; Pointoperator/ (ConstLine A,ConstLine B) {DoubleT = ((B.P-A.P)% B.V)/(a.v% B.V);returnA.P + a.v * t;}DoubleDis (point P, line L) {return fabs(l.v% (P-L.P))/Length (L.V);}DoubleAngle (line A, line B) {DoubleAns = angle (A.V, B.V);returnFmin (ans, pi-ans);}structseg{point P1, p2; Seg () {}; Seg (Point P11, point p22) {p1 = P11, p2 = P22;}};BOOL operator/ (ConstSeg A,ConstSeg b) {//need Change returnSGN ((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/ (ConstLine A,ConstSeg b) {returnSGN (a.v% (B.P1-A.P)) * SGN (a.v% (B.P2-A.P)) <=0;}BOOLPointonseg (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 200010intN Point P[n]; Point P1, p2; Point Readpoi () {intx, y; x = Read (), y = Read ();returnPoint (x, y);}voidKuoda () { for(inti = n +1; I <= n + N; i++) {P[i] = p[i-n]; }}voidSolve () {ll ans =0; for(inti =1; I <= N; i++) {intL, 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;ElseL = mid +1; }intTP1 = 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;ElseR = Mid-1; }intTP2 = l;if(TP1! = TP2) ans + = TP1-TP2-1; } ans >>=1;cout<<ans<<endl;}intMain () {Freopen ("Kingdom.in","R", stdin); Freopen ("Kingdom.out","W", stdout); while(~scanf("%d", &n) && n >0){ for(inti =1; I <= N; i++) P[i] = Readpoi (); P1 = Readpoi (); P2 = Readpoi (); Kuoda (); Solve (); }return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Codeforces Gym 100517 (two points, same direction)