ALORA7 - Editorial

Problem Link : Deathly Hallows

Author : Ritesh Gupta
Tester : Romit Kumar
Editorialist : Ritesh Gupta

Pre-Requisite : FFT, GCD, Seive Theory.

Problem : You are given two parallel lines. The first line contains n distinct points on it and the second line contains m distinct points on it. You have to connect each point of the first line to every point of the second line. Now in all the line segments, you have to count the number of pair of segments which satisfy the below-given property.

Let P_{xy} be a line segment which connects a_x point of the first line with b_y point of the second line. Similarly, P_{uv} be a line segment which connects a_u point of the first line with b_v point of the second line. The pair of interaction (P_{xy}, P_{uv}) will favor Harry if they follow certain conditions:

  • P_{xy} is parallel to P_{uv}.
  • GCD(a_x, b_y) \neq MIN(a_x, b_y) \space or \space GCD(a_u, b_v) \neq MIN(a_u, b_v)

Explanation : First forget about the second condition and find the answer which satisfies the first condition. The two line segment P_{xy} and P_{uv} are parallel when (a_x - b_y == a_u - b_v). Thus all pairs (a_x, b_y) whose difference a_x - b_y will be parallel to each other. For a given difference d, if there are k pairs, number of parallel lines for that difference will be n*(n-1)/2.

All that’s required is to consider all pairs of the given form and count the number the number of pairs for every difference. This could be done naively, however, the time complexity will be O(n^2).

To do this effectively, we need to consider two polynomial corresponding to given parallel lines. First polynomial will be of the form A(x) = a_1x^1 + a_2x^2 + ... + a_nx^n, where a_i is 1 if i_{th} point is an energy point in the orange jet. Similarly, the other polynomial will be of the form B(x) = b_1x^{-1} + b_2x^{-2} + ... + b_nx^{-n}, where b_i is 1 if ith point is an energy point in green jet.

If we multiply these two polynomials, the power of x represents the difference between certain pairs of point and the coefficients represent the count of those pairs. Using this information we can find the required answer. Multiplication of polynomial can be done by fft in O(nlogn).

Now let us consider the second condition in two phases.

  • First, we consider all the line segments P_{xy} in which a_x divide b_y where a_x and b_y belong to first and second line respectively. But we also need to find the count of k-difference line segments for every k from (0,2e5). For that, we create an array A of length 2e5 with the initial value of the elements is zero. Now what we have to do is iterate over points of the first line in increasing order and for every element, we run an inner loop over starting from twice the value of the first line element up to 2e5 with increment it by the integer value of the first line element. If we find a point that corresponds to the positions visited by inner loop then we increment the (x-y) position of the array A where x is the point on the first line and y is the current value of inner loop. After this, we decrease our current answer by k*(k-1)/2 for all k in the array A where k treated as an element.

  • Similarly, we consider all the line segments P_{xy} in which b_y divide a_x where a_x and b_y belong to first and second line respectively and perform the same algorithm as above mentioned.

     for(int i=1;i<=200000;i++)
     {
         if(a[i])
         {
             for(int j=2*i;j<=200000;j+=i)
             {
                 if(b[j])
                     cnt1[j-i]++;
             }
         }
    
         if(b[i])
         {
             for(int j=2*i;j<=200000;j+=i)
             {
                 if(a[j])
                     cnt2[j-i]++;
             }
    
             if(a[i] == b[i])
                 cnt1[0]++;
         }
     }
    
     for(int i=0;i<=200000;i++)
         ans -= (cnt1[i]*(cnt1[i]-1))/2, ans -= (cnt2[i]*(cnt2[i]-1))/2;
    

Here array a treated as points on the first line and b treated as points on the second line and array cnt1 and cnt2 are used as array A in first and second part respectively. Apart from it, we have to also exclude the count of the pair of line segments in which both line segments are perpendicular to the lines. For which we use third if statements shown in above code sniping.

Time Complexity : O(nlogn + NloglogN) where N = 2e5.
Setter Solution : Link

2 Likes

The setter solution doesn’t pass the samples.