Link to this code:
https://cses.fi/paste/fa875061784c3036334466///
// Created by michaelyang on 4:57 PM Jan 09 2022.
// Problem: pl in Polygon
// check if points are inside polygon
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#define f first
#define s second
#define fastio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pl;
const int MOD=1e9+7;
const int N=1e5+5;
string onSegment(pl p,pl q,pl r){
if (q.f<max(p.f,r.f)&&q.f>min(p.f,r.f)&&q.s<max(p.s,r.s)&&q.s>min(p.s,r.s)) return "NOTON";
if (((q.f==max(p.f,r.f)||q.f==min(p.f,r.f))&&(q.s<=max(p.s,r.s)&&q.s>=min(p.s,r.s)))||((q.f<=max(p.f,r.f)&&q.f>=min(p.f,r.f))&&(q.s==max(p.s,r.s)||q.s==min(p.s,r.s)))) return "ENDPOINT";
return "ON";
}
// To find orientation of ordered triplet (p, q, r).
// The function returns following values
// 0 --> p, q and r are collinear
// 1 --> Clockwise
// 2 --> Counterclockwise
int orientation(pl p,pl q,pl r){
int val=(q.s-p.s)*(r.f-q.f)-
(q.f-p.f)*(r.s-q.s);
if (val==0) return 0; // collinear
return (val>0)?1:2; // clock or counterclock wise
}
// The function that returns true if line segment 'p1q1'
// and 'p2q2' intersect.
bool doIntersect(pl p1,pl q1,pl p2,pl q2){
// Find the four orientations needed for general and
// special cases
int o1=orientation(p1,q1,p2);
int o2=orientation(p1,q1,q2);
int o3=orientation(p2,q2,p1);
int o4=orientation(p2,q2,q1);
// General case
if (o1!=o2&&o3!=o4)
return true;
// Special Cases
// p1, q1 and p2 are collinear and p2 lies on segment p1q1
if (o1==0&&onSegment(p1,p2,q1)=="ON") return true;
// p1, q1 and p2 are collinear and q2 lies on segment p1q1
if (o2==0&&onSegment(p1,q2,q1)=="ON") return true;
// p2, q2 and p1 are collinear and p1 lies on segment p2q2
if (o3==0&&onSegment(p2,p1,q2)=="ON") return true;
// p2, q2 and q1 are collinear and q1 lies on segment p2q2
if (o4==0&&onSegment(p2,q1,q2)=="ON") return true;
return false; // Doesn't fall in any of the above cases
}
// Returns true if the pl p lies inside the polygon[] with n vertices
string isInside(vector<pl> polygon,pl p){
int n=polygon.size();
// There must be at least 3 vertices in polygon[]
if (n<3) return "OUTSIDE";
// Create a pl for line segment from p to infinite
pl extreme={1e9+5,p.s};
// Count intersections of the above line with sides of polygon
int count=0,i=0;
do{
int next=(i+1)%n;
// Check if the line segment from 'p' to 'extreme' intersects
// with the line segment from 'polygon[i]' to 'polygon[next]'
if (doIntersect(polygon[i],polygon[next],p,extreme)){
// If the pl 'p' is collinear with line segment 'i-next',
// then check if it lies on segment. If it lies, return true,
// otherwise false
if (orientation(polygon[i],p,polygon[next])==0){
if (onSegment(polygon[i],p,polygon[next])!="NOTON") return "BOUNDARY";
else return "OUTSIDE";
}
count++;
}
i=next;
} while (i!=0);
// Return true if count is odd, false otherwise
if (count%2) return "INSIDE";
else return "OUTSIDE";
}
int main(){
fastio
int n,m;
cin>>n>>m;
vector<pl> polygon;
for (int i=0;i<n;i++){
int a,b;
cin>>a>>b;
polygon.push_back({a,b});
}
for (int i=0;i<m;i++){
int a,b;
cin>>a>>b;
cout<<isInside(polygon,{a,b})<<endl;
}
}