给定三个整数N,A,B,当将范围为[1,N]的A或B整除的整数之和除以该范围内的整数数时,任务是找到余数。
注意:数字A和B是互质的。
例子:
Input: N = 88, A = 11, B = 8
Output: 8
Explanation:
There are a total of 18 numbers in the range [1, 88] which are divisible by either 8 or 11. They are:
{ 8, 11, 16, 22, 24, 32, 33, 40, 44, 48, 55, 56, 64, 66, 72, 77, 80, 88 }. Therefore, the sum of these numbers is 836. Therefore, 836 % 18 = 8.
Input: N = 100, A = 7, B = 19
Output: 13
Explanation:
There are a total of 19 numbers in the range [1, 100] which are divisible by either 7 or 19. They are:
{ 7, 14, 19, 21, 28, 35, 38, 42, 49, 56, 57, 63, 70, 76, 77, 84, 91, 95, 98 }. Therefore, the sum of these numbers is 1020. Therefore, 1020 % 19 = 13.
天真的方法:天真的方法是运行从1到N的循环,并计算所有可被A或B整除的数字,同时将这些数字加到变量中以求和。
时间复杂度: O(N)
高效方法:高效方法是使用除法。
- 通过使用除法,可以在恒定时间内找到可被A或B整除的数字的计数。这个想法是:
- 用N除以A即可得到在[1,N]范围内被A整除的数字计数。
- 用N除以B ,得到在[1,N]范围内被B整除的数的计数。
- 将N除以A * B即可得到A和B可除的数。
- 将在步骤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) 。