Firstly we find all the vectors by doing Pn - Pn-1.
I will reduce the question to this statement : Find a line such that i can group a set containing all elements in [ L , R ] in one side of the line and rest will be in other side of the line.
the elements are basically the vectors. Geometrically a dot product will act as a projection , same side is '+" and opposite side is ’ - '.
Now the real question is how will i find such lines?
we could do a trick here , Lets imagine a (2e9 * 2e9) square .(thats the max constraint)
obviously the vectors obtained with respect to origin will meet the square at some point.
Find the nearest clockwise left of the points.
( I will call this line as Epsilon vector)
For example :
vector (1 , 1) meets the square at (2e9 , 2e9) , hence the nearest clockwise left point lying on the square is (2e9 - 1 , 2e9).
vector(2 , 1) meets the square at (2e9 , 1e9) , so the point is (2e9 , 1e9 + 1).
As i took Clockwise left Line of this vectors , if i use epsilon vector( vector B ) , i will have B on clockwise right side of my line. So , intuitively the Dot product with right perpendicular of this line will always give me ‘+’ for B and left perpendicular will give ‘-’ for B.
For Sub-task 1 , you could just check dot product of each vector with each perpendicular of(epsilon vector) . So that would be O(N*N).
N perp(epsilon vectors) being checked with all N vectors.
Dot product takes O(1) and checking for required condition to have continuous elements to have dot product as ‘+’ value takes O(N).
Code snippet for subtask 1.
ans = {0 , 0};
for(auto p : bl) //bl has all pairs of epsilon vectors (pairs)
{
int dot[n];
// perpendicular(x,y) = (-y , x)
pii pp = {-p.second , p.first}; //pp = perpendicular of the taken vector.
int pos=0; //Total Positive Dot products
for(int i=0 ; i<n ; i++)
{
dot[i] = pp.first*v[i].first + pp.second*v[i].second;
if(dot[i] >0)pos++;
}
int continuous_pos=0;
int tracker=0;
for(int i=0 ; i<n ; i++)
{
if(dot[i] == 0)break;
if(dot[i] > 0)
{
tracker++;
}
else
{
continuous_pos = max(continuous_pos , tracker);
tracker=0;
}
}
continuous_pos = max(continuous_pos , tracker);
if(continuous_pos == pos)
{
ans = pp;
break;
}
}
cout<<ans.first<<" "<<ans.second<<endl;
For Subtask 2 , we can have an observation that if we find all the epsilon vectors and move in clockwise or anti-clockwise manner.
Assign epsilon(A) as +A and assign -epsilon(A) as -A when we encounter.
We could actually use this to maintain a set and update accordingly.
Your set maybe assigned as the elements in the right of the rotating line.
now to check if we have continuos sequence of numbers in the set , A small trick can be used.
if set has {3,4,5} i could just check is Sum(set) = ( PP+1 - CC-1)/2
where P = (first_element + set.size() - 1)
and C = (first_element).
Comparator to sort coordinates in clockwise fashion.
bool cmp( const pair<pii , int> &a , const pair<pii , int> &b)
{
ld angle1 = atan2(a.first.second , a.first.first);
ld angle2 = atan2(b.first.second , b.first.first);
if(angle1 > angle2)return 1;
else return 0;
}
Now the rest part is exercise for you.