Question of the day _ interval common divisor of small M _ number theory

interval common divisor of small M

Time Limit:1 Ms| Memory Limit:10 MB
Difficulty:0

[Problem] [Rank]

Description
Xiao M is already familiar with the greatest common divisor. Today, on a whim, she wants to know the greatest common divisor of the interval. Two numbers a, b, then there are n groups of queries, each group of query [L, R], output the largest common divisor of a, b in the interval [L, R], no output - 1 .
Input
Enter a, b on the first line, ( 1  ≤ a, b ≤  10 ^ 9 )
Enter n on the second line, ( 1  ≤ n ≤  10 ^ 4 )
Then the next n lines, each line [L, R]. ( 1  ≤ L ≤ R ≤  10 ^ 9 )
Output
Output the result of each query.
Sample Input
9 27
3 
1 5
10 11
9 11
Sample Output
3
-1
9

If the problem is not considering the limit situation, it is quite simple. It is to first calculate the real greatest common divisor of these two numbers, and then compare this with the relative situation of the interval.

When the greatest common divisor is greater than this interval, exhaustiveness is used, starting from the right endpoint of the interval to the left endpoint. Of course, this should be a waste of time.

If you don't do this, you should calculate all the divisors of these two numbers (you only need to calculate the divisors to the number under the square root), and then process them to find the common ones, that is, these two Divisors of numbers,

Then compare with this interval.

But in this case, it is still a bit troublesome. Later, I found that the divisor of the greatest common divisor of two numbers is the divisor of these two numbers, so it is good to calculate the divisor of the greatest common divisor, and there is no need to compare and deduplicate. .

Code:

 

 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int gcd(int a, int b)
{
    if (b == 0)
    {
        return a;
    }
    else
    {
        return gcd(b, a % b);
    }
}

int cmp_1(const void *a, const void *b)
{
    return *(int *) a - *(int *) b;
}

int arr[10000];

intmain ()
{
    int a, b;
    int n;
    int l, r;
    int i, j;
    int c;
    int top;
    int flag;
    while (scanf("%d%d", &a, &b) != EOF)
    {
        top = 0;
        
        memset(arr, - 1 , sizeof (arr));
         // Calculate the greatest common divisor of a and b 
        if (a >= b)
        {
            c = gcd(a, b);
        }
        else
        {
            c = gcd(b, a);
        }
        // find the divisor of the greatest common divisor 
        for (j = 1 ; j * j <= c; j++ )
        {
            if (c % j == 0)
            {
                arr[top++] = j;
                arr[top++] = c / j;
            }
        }
        // Then sort 
        qsort(arr, top, sizeof ( int ), cmp_1);
        scanf("%d", &n);
        while (n--)
        {
            flag = 1;
            scanf("%d%d", &l, &r);
            if (c < l)
            {
                printf("-1\n");
            }
            else if (c >= l && c <= r)
            {
                printf("%d\n", c);
            }
            else
            {
                for (j = top - 1; j >= 0; j--)
                {
                    if (arr[j] >= l && arr[j] <= r)
                    {
                        flag = 1;
                        printf("%d\n", arr[j]);
                        break;
                    }
                }
                if (flag == 0)
                {
                    printf("-1\n");
                }
            }


        }
    }

    return 0;
}

What should be noted in this topic is that some calculations may only need to be calculated once for many sets of data, don't misplace and waste time. For example, the calculation of the greatest common divisor of this question does not need to be placed in while(n--), it can be done outside.

 

 

Reprinted in: https://www.cnblogs.com/virusdefender/p/3465187.html

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324872463&siteId=291194637