📌  相关文章
📜  在给定的1到N范围内查找和计算互素A或B的总因子

📅  最后修改于: 2021-04-26 07:09:02             🧑  作者: Mango

给定三个整数N,A,B,当将范围为[1,N]的A或B整除的整数之和除以该范围内的整数数时,任务是找到余数。

注意:数字A和B是互质的。

例子:

天真的方法:天真的方法是运行从1到N的循环,并计算所有可被A或B整除的数字,同时将这些数字加到变量中以求和。

时间复杂度: O(N)

高效方法:高效方法是使用除法。

  • 通过使用除法,可以在恒定时间内找到可被AB整除的数字计数。这个想法是:
    1. 用N除以A即可得到在[1,N]范围内被A整除的数字计数。
    2. 用N除以B ,得到在[1,N]范围内被B整除的数的计数。
    3. 将N除以A * B即可得到A和B可除的数。
    4. 步骤1和步骤2中获得的值相加,然后减去步骤3中获得的值,以除去已计数两次的数字。
  • 由于我们甚至有兴趣查找在此范围内可整除数字,因此我们的想法是通过以下方式减少检查条件的次数:
    • 除了完全依赖一个循环,我们还可以使用两个循环
    • 一个循环是找到可被A整除的数字。与其将值增加1,我们从A开始循环,然后将A增加。这大大减少了比较次数。
    • 类似地,另一个循环用于查找可被B整除的数字。
    • 再次,由于数字中可能存在重复,因此将数字存储在一个集合中,这样就不会重复。
  • 一旦找到数字的计数和总和,就可以直接进行模运算来计算最终答案。

下面是上述方法的实现:

CPP
// C++ implementation of the above approach
#include 
#include 
#include 
#define ll long long
using namespace std;
  
// Function to return the count of numbers
// which are divisible by both A and B in
// the range [1, N] in constant time
ll int countOfNum(ll int n, ll int a, ll int b)
{
    ll int cnt_of_a, cnt_of_b, cnt_of_ab, sum;
  
    // Compute the count of numbers divisible by
    // A in the range [1, N]
    cnt_of_a = n / a;
  
    // Compute the count of numbers divisible by
    // B in the range [1, N]
    cnt_of_b = n / b;
  
    // Adding the counts which are
    // divisible by A and B
    sum = cnt_of_b + cnt_of_a;
  
    // The above value might contain repeated
    // values which are divisible by both
    // A and B. Therefore, the count of numbers
    // which are divisible by both A and B are found
    cnt_of_ab = n / (a * b);
  
    // The count computed above is subtracted to
    // compute the final count
    sum = sum - cnt_of_ab;
  
    return sum;
}
  
// Function to return the sum of numbers
// which are divisible by both A and B
// in the range [1, N]
ll int sumOfNum(ll int n, ll int a, ll int b)
{
    ll int i;
    ll int sum = 0;
  
    // Set to store the numbers so that the
    // numbers are not repeated
    set ans;
  
    // For loop to find the numbers
    // which are divisible by A and insert
    // them into the set
    for (i = a; i <= n; i = i + a) {
        ans.insert(i);
    }
  
    // For loop to find the numbers
    // which are divisible by A and insert
    // them into the set
    for (i = b; i <= n; i = i + b) {
        ans.insert(i);
    }
  
    // For loop to iterate through the set
    // and find the sum
    for (auto it = ans.begin();
         it != ans.end(); it++) {
        sum = sum + *it;
    }
  
    return sum;
}
  
// Driver code
int main()
{
    ll int N = 88;
    ll int A = 11;
    ll int B = 8;
  
    ll int count = countOfNum(N, A, B);
    ll int sumofnum = sumOfNum(N, A, B);
  
    cout << sumofnum % count << endl;
  
    return 0;
}
.


Java
// Java implementation of the above approach
  
import java.util.*;
// Function to return the count of numbers
// which are divisible by both A and B in
// the range [1, N] in constant time
  
class GFG 
{
  
    static int countOfNum( int n,  int a, int b)
    {
        int cnt_of_a, cnt_of_b, cnt_of_ab, sum;
      
        // Compute the count of numbers divisible by
        // A in the range [1, N]
        cnt_of_a = n / a;
      
        // Compute the count of numbers divisible by
        // B in the range [1, N]
        cnt_of_b = n / b;
      
        // Adding the counts which are
        // divisible by A and B
        sum = cnt_of_b + cnt_of_a;
      
        // The above value might contain repeated
        // values which are divisible by both
        // A and B. Therefore, the count of numbers
        // which are divisible by both A and B are found
        cnt_of_ab = n / (a * b);
      
        // The count computed above is subtracted to
        // compute the final count
        sum = sum - cnt_of_ab;
      
        return sum;
    }
      
    // Function to return the sum of numbers
    // which are divisible by both A and B
    // in the range [1, N]
    static int sumOfNum( int n,  int a, int b)
    {
        int i;
        int sum = 0;
      
        // Set to store the numbers so that the
        // numbers are not repeated
        Set< Integer> ans =  new HashSet();
      
        // For loop to find the numbers
        // which are divisible by A and insert
        // them into the set
        for (i = a; i <= n; i = i + a) {
            ans.add(i);
        }
      
        // For loop to find the numbers
        // which are divisible by A and insert
        // them into the set
        for (i = b; i <= n; i = i + b) {
            ans.add(i);
        }
      
        // For loop to iterate through the set
        // and find the sum
        for (Integer it : ans) {
            sum = sum + it;
        }
      
        return sum;
    }
      
    // Driver code
    public static void main (String []args)
    {
        int N = 88;
        int A = 11;
        int B = 8;
      
        int count = countOfNum(N, A, B);
        int sumofnum = sumOfNum(N, A, B);
      
        System.out.print(sumofnum % count);
    } 
}
  
// This code is contributed by chitranayal


Python3
# Python3 implementation of the above approach
  
# Function to return the count of numbers
# which are divisible by both A and B in
# the range [1, N] in constant time
def countOfNum(n, a, b):
    cnt_of_a, cnt_of_b, cnt_of_ab, sum = 0, 0, 0, 0
  
    # Compute the count of numbers divisible by
    # A in the range [1, N]
    cnt_of_a = n // a
  
    # Compute the count of numbers divisible by
    # B in the range [1, N]
    cnt_of_b = n // b
  
    # Adding the counts which are
    # divisible by A and B
    sum = cnt_of_b + cnt_of_a
  
    # The above value might contain repeated
    # values which are divisible by both
    # A and B. Therefore, the count of numbers
    # which are divisible by both A and B are found
    cnt_of_ab = n // (a * b)
  
    # The count computed above is subtracted to
    # compute the final count
    sum = sum - cnt_of_ab
  
    return sum
  
# Function to return the sum of numbers
# which are divisible by both A and B
# in the range [1, N]
def sumOfNum(n, a, b):
  
    i = 0
    sum = 0
  
    # Set to store the numbers so that the
    # numbers are not repeated
    ans = dict()
  
    # For loop to find the numbers
    # which are divisible by A and insert
    # them into the set
    for i in range(a, n + 1, a):
        ans[i] = 1
  
    # For loop to find the numbers
    # which are divisible by A and insert
    # them into the set
    for i in range(b, n + 1, b):
        ans[i] = 1
  
    # For loop to iterate through the set
    # and find the sum
    for it in ans:
        sum = sum + it
    return sum
  
# Driver code
if __name__ == '__main__':
    N = 88
    A = 11
    B = 8
  
    count = countOfNum(N, A, B)
    sumofnum = sumOfNum(N, A, B)
  
    print(sumofnum % count)
  
# This code is contributed by mohit kumar 29


C#
// C# implementation of the above approach
using System;
using System.Collections.Generic;
  
class GFG 
{
    // Function to return the count of numbers
    // which are divisible by both A and B in
    // the range [1, N] in constant time
   
    static int countOfNum( int n,  int a, int b)
    {
        int cnt_of_a, cnt_of_b, cnt_of_ab, sum;
       
        // Compute the count of numbers divisible by
        // A in the range [1, N]
        cnt_of_a = n / a;
       
        // Compute the count of numbers divisible by
        // B in the range [1, N]
        cnt_of_b = n / b;
       
        // Adding the counts which are
        // divisible by A and B
        sum = cnt_of_b + cnt_of_a;
       
        // The above value might contain repeated
        // values which are divisible by both
        // A and B. Therefore, the count of numbers
        // which are divisible by both A and B are found
        cnt_of_ab = n / (a * b);
       
        // The count computed above is subtracted to
        // compute the readonly count
        sum = sum - cnt_of_ab;
       
        return sum;
    }
       
    // Function to return the sum of numbers
    // which are divisible by both A and B
    // in the range [1, N]
    static int sumOfNum( int n,  int a, int b)
    {
        int i;
        int sum = 0;
       
        // Set to store the numbers so that the
        // numbers are not repeated
        HashSet< int> ans =  new HashSet();
       
        // For loop to find the numbers
        // which are divisible by A and insert
        // them into the set
        for (i = a; i <= n; i = i + a) {
            ans.Add(i);
        }
       
        // For loop to find the numbers
        // which are divisible by A and insert
        // them into the set
        for (i = b; i <= n; i = i + b) {
            ans.Add(i);
        }
       
        // For loop to iterate through the set
        // and find the sum
        foreach (int it in ans) {
            sum = sum + it;
        }
       
        return sum;
    }
       
    // Driver code
    public static void Main(String []args)
    {
        int N = 88;
        int A = 11;
        int B = 8;
       
        int count = countOfNum(N, A, B);
        int sumofnum = sumOfNum(N, A, B);
       
        Console.Write(sumofnum % count);
    } 
}
  
// This code is contributed by 29AjayKumar


输出:
8

时间复杂度分析:

  • 运行for循环以查找可被A整除的数字所花费的时间为O(N / A)
  • 运行for循环以查找可被B整除的数字所花费的时间为O(N / B)
  • 因此,总体时间复杂度为O(N / A)+ O(N / B)