给定两个数字N和K 。可以通过在每个位置放置从1 到 K 的数字来创建长度为N的序列A 1 , A 2 , ….A N ,总共有 K N 个序列。任务是找到所有形成的序列的 GCD 之和。
注意:答案可能很大,所以取模10 9 + 7 。
例子:
Input: N = 3, K = 2
Output: 9
Explanation:
The gcd of all the subsequences are:
gcd(1, 1, 1) = 1
gcd(1, 1, 2) = 1
gcd(1, 2, 1) = 1
gcd(1, 2, 2) = 1
gcd(2, 1, 1) = 1
gcd(2, 1, 2) = 1
gcd(2, 2, 1) = 1
gcd(2, 2, 2) = 2
The sum of GCD is 1 + 1 + 1 + 1 + 1 + 1 + 1 + 2 = 9.
Input: N = 3, K = 200
Output: 10813692
朴素的方法:这个想法是递归地生成长度为N 的所有可能的子序列。所形成的所有序列的 GCD 之和就是所需的结果。
下面是上述方法的实现:
C++
// C++ implementation of the above approach
#include
using namespace std;
const int MOD = (int)1e9 + 7;
// A recursive function that generates all
// the sequence and find GCD
int calculate(int pos, int g, int n, int k)
{
// If we reach the sequence of length N
// g is the GCD of the sequence
if (pos == n) {
return g;
}
// Initialise answer to 0
int answer = 0;
// Placing all possible values at this
// position and recursively find the
// GCD of the sequence
for (int i = 1; i <= k; i++) {
// Take GCD of GCD calculated uptill
// now i.e. g with current element
answer = (answer % MOD
+ calculate(pos + 1, __gcd(g, i), n, k) % MOD);
// Take modulo to avoid overflow
answer %= MOD;
}
// Return the final answer
return answer;
}
// Function that finds the sum of GCD
// of all the subsequence of N length
int sumofGCD(int n, int k)
{
// Recursive function that generates
// the sequence and return the GCD
return calculate(0, 0, n, k);
}
// Driver Code
int main()
{
int N = 3, K = 2;
// Function Call
cout << sumofGCD(N, K);
return 0;
}
Java
// Java implementation of the above approach
class GFG{
static int MOD = (int)1e9 + 7;
// A recursive function that generates all
// the sequence and find GCD
static int calculate(int pos, int g, int n, int k)
{
// If we reach the sequence of length N
// g is the GCD of the sequence
if (pos == n) {
return g;
}
// Initialise answer to 0
int answer = 0;
// Placing all possible values at this
// position and recursively find the
// GCD of the sequence
for (int i = 1; i <= k; i++) {
// Take GCD of GCD calculated uptill
// now i.e. g with current element
answer = (answer % MOD
+ calculate(pos + 1, __gcd(g, i), n, k) % MOD);
// Take modulo to astatic void overflow
answer %= MOD;
}
// Return the final answer
return answer;
}
// Function that finds the sum of GCD
// of all the subsequence of N length
static int sumofGCD(int n, int k)
{
// Recursive function that generates
// the sequence and return the GCD
return calculate(0, 0, n, k);
}
static int __gcd(int a, int b)
{
return b == 0? a:__gcd(b, a % b);
}
// Driver Code
public static void main(String[] args)
{
int N = 3, K = 2;
// Function Call
System.out.print(sumofGCD(N, K));
}
}
// This code is contributed by Rajput-Ji
Python3
# Pyhton3 implementation of the
# above approach
MOD = 1e9 + 7
def gcd(a, b):
if (b == 0):
return a
else:
return gcd(b, a % b)
# A recursive function that generates all
# the sequence and find GCD
def calculate(pos, g, n, k):
# If we reach the sequence of length N
# g is the GCD of the sequence
if (pos == n):
return g
# Initialise answer to 0
answer = 0
# Placing all possible values at this
# position and recursively find the
# GCD of the sequence
for i in range(1, k + 1):
# Take GCD of GCD calculated uptill
# now i.e. g with current element
answer = (answer % MOD +
calculate(pos + 1,
gcd(g, i), n, k) % MOD)
# Take modulo to avoid overflow
answer %= MOD
# Return the final answer
return answer
# Function that finds the sum of GCD
# of all the subsequence of N length
def sumofGCD(n, k):
# Recursive function that generates
# the sequence and return the GCD
return calculate(0, 0, n, k)
# Driver code
if __name__=="__main__":
N = 3
K = 2
# Function Call
print(sumofGCD(N, K))
# This code is contributed by rutvik_56
C#
// C# implementation of the above approach
using System;
public class GFG{
static int MOD = (int)1e9 + 7;
// A recursive function that generates all
// the sequence and find GCD
static int calculate(int pos, int g, int n, int k)
{
// If we reach the sequence of length N
// g is the GCD of the sequence
if (pos == n) {
return g;
}
// Initialise answer to 0
int answer = 0;
// Placing all possible values at this
// position and recursively find the
// GCD of the sequence
for (int i = 1; i <= k; i++) {
// Take GCD of GCD calculated uptill
// now i.e. g with current element
answer = (answer % MOD
+ calculate(pos + 1, __gcd(g, i), n, k) % MOD);
// Take modulo to astatic void overflow
answer %= MOD;
}
// Return the readonly answer
return answer;
}
// Function that finds the sum of GCD
// of all the subsequence of N length
static int sumofGCD(int n, int k)
{
// Recursive function that generates
// the sequence and return the GCD
return calculate(0, 0, n, k);
}
static int __gcd(int a, int b)
{
return b == 0 ? a : __gcd(b, a % b);
}
// Driver code
public static void Main(String[] args)
{
int N = 3, K = 2;
// Function call
Console.Write(sumofGCD(N, K));
}
}
// This code is contributed by 29AjayKumar
Javascript
C++
// C++ implementation of the above approach
#include
using namespace std;
const int MOD = (int)1e9 + 7;
// Function to find a^b in log(b)
int fastexpo(int a, int b)
{
int res = 1;
a %= MOD;
while (b) {
if (b & 1)
res = (res * a) % MOD;
a *= a;
a %= MOD;
b >>= 1;
}
return res;
}
// Function that finds the sum of GCD
// of all the subsequence of N length
int sumofGCD(int n, int k)
{
// To stores the number of sequences
// with gcd i
int count[k + 1] = { 0 };
// Find contribution of each gcd
// to happen
for (int g = k; g >= 1; g--) {
// To count multiples
int count_multiples = k / g;
// possible sequences with
// overcounting
int temp;
temp = fastexpo(count_multiples, n);
// to avoid overflow
temp %= MOD;
// Find extra element which will
// not form gcd = i
int extra = 0;
// Find overcounting
for (int j = g * 2; j <= k; j += g) {
extra = (extra + count[j]);
extra %= MOD;
}
// Remove the overcounting
count[g] = (temp - extra + MOD);
count[g] %= MOD;
}
// To store the final answer
int sum = 0;
int add;
for (int i = 1; i <= k; ++i) {
add = (count[i] % MOD * i % MOD);
add %= MOD;
sum += add;
sum %= MOD;
}
// Return Final answer
return sum;
}
// Driver Code
int main()
{
int N = 3, K = 2;
// Function call
cout << sumofGCD(N, K);
return 0;
}
Java
// Java implementation of the above approach
class GFG{
static int MOD = (int)1e9 + 7;
// Function to find a^b in log(b)
static int fastexpo(int a, int b)
{
int res = 1;
a %= MOD;
while (b > 0) {
if (b % 2 == 1)
res = (res * a) % MOD;
a *= a;
a %= MOD;
b >>= 1;
}
return res;
}
// Function that finds the sum of GCD
// of all the subsequence of N length
static int sumofGCD(int n, int k)
{
// To stores the number of sequences
// with gcd i
int []count = new int[k + 1];
// Find contribution of each gcd
// to happen
for (int g = k; g >= 1; g--) {
// To count multiples
int count_multiples = k / g;
// possible sequences with
// overcounting
int temp;
temp = fastexpo(count_multiples, n);
// to astatic void overflow
temp %= MOD;
// Find extra element which will
// not form gcd = i
int extra = 0;
// Find overcounting
for (int j = g * 2; j <= k; j += g) {
extra = (extra + count[j]);
extra %= MOD;
}
// Remove the overcounting
count[g] = (temp - extra + MOD);
count[g] %= MOD;
}
// To store the final answer
int sum = 0;
int add;
for (int i = 1; i <= k; ++i) {
add = (count[i] % MOD * i % MOD);
add %= MOD;
sum += add;
sum %= MOD;
}
// Return Final answer
return sum;
}
// Driver Code
public static void main(String[] args)
{
int N = 3, K = 2;
// Function call
System.out.print(sumofGCD(N, K));
}
}
// This code is contributed by PrinciRaj1992
Python3
# Python3 implementation of the above approach
MOD = (int)(1e9 + 7)
# Function to find a^b in log(b)
def fastexpo(a, b) :
res = 1
a = a % MOD
while (b > 0) :
if ((b & 1) != 0) :
res = (res * a) % MOD
a = a * a
a = a % MOD
b = b >> 1
return res
# Function that finds the sum of GCD
# of all the subsequence of N length
def sumofGCD(n, k) :
# To stores the number of sequences
# with gcd i
count = [0] * (k + 1)
# Find contribution of each gcd
# to happen
for g in range(k, 0, -1) :
# To count multiples
count_multiples = k // g
# possible sequences with
# overcounting
temp = fastexpo(count_multiples, n)
# to avoid overflow
temp = temp % MOD
# Find extra element which will
# not form gcd = i
extra = 0
# Find overcounting
for j in range(g * 2, k + 1, g) :
extra = extra + count[j]
extra = extra % MOD
# Remove the overcounting
count[g] = temp - extra + MOD
count[g] = count[g] % MOD
# To store the final answer
Sum = 0
for i in range(1, k + 1) :
add = count[i] % MOD * i % MOD
add = add % MOD
Sum = Sum + add
Sum = Sum % MOD
# Return Final answer
return Sum
# Driver code
N, K = 3, 2
# Function call
print(sumofGCD(N, K))
# This code is contributed by divyeshrabadiya07.
C#
// C# implementation of the above approach
using System;
class GFG{
static int MOD = (int)1e9 + 7;
// Function to find a^b in log(b)
static int fastexpo(int a, int b)
{
int res = 1;
a %= MOD;
while (b > 0) {
if (b % 2 == 1)
res = (res * a) % MOD;
a *= a;
a %= MOD;
b >>= 1;
}
return res;
}
// Function that finds the sum of GCD
// of all the subsequence of N length
static int sumofGCD(int n, int k)
{
// To stores the number of sequences
// with gcd i
int []count = new int[k + 1];
// Find contribution of each gcd
// to happen
for (int g = k; g >= 1; g--) {
// To count multiples
int count_multiples = k / g;
// possible sequences with
// overcounting
int temp;
temp = fastexpo(count_multiples, n);
// to astatic void overflow
temp %= MOD;
// Find extra element which will
// not form gcd = i
int extra = 0;
// Find overcounting
for (int j = g * 2; j <= k; j += g) {
extra = (extra + count[j]);
extra %= MOD;
}
// Remove the overcounting
count[g] = (temp - extra + MOD);
count[g] %= MOD;
}
// To store the readonly answer
int sum = 0;
int add;
for (int i = 1; i <= k; ++i) {
add = (count[i] % MOD * i % MOD);
add %= MOD;
sum += add;
sum %= MOD;
}
// Return Final answer
return sum;
}
// Driver Code
public static void Main(String[] args)
{
int N = 3, K = 2;
// Function call
Console.Write(sumofGCD(N, K));
}
}
// This code is contributed by Princi Singh
Javascript
输出:
9
时间复杂度: O(N K )
有效的方法:
- 由于序列的编号可以从1 到 K ,因此序列的 gcd 值将在 1 到 K 的范围内。
- 让count[i]表示 gcd = i 的序列数。对于 i = 1,我们对哪些元素可以属于该序列没有限制,因此在N 个位置中的每一个,我们都有K 个放置元素的可能性,使总序列成为K N 。但是得到的序列可能有更高的 GCD,所以减去过度计数的值:
count[1] = KN - count[2] - count[3] - count[4] - .... count[K]
- 类似地,对于 i = 2,由于每个数字都必须是 2 的倍数,因此我们在每个位置都有K/2 种可能性,使总数为(K/2) N 。并通过用所有 2 的倍数的 GCD 减去序列计数来减去所有过度计数的值。
count[2] = (K/2)N - count[4] - count[6] - count[8] - ... all multiples of 2
- 类似地,对每个gcd值按照上述步骤到K。
- 每个 GCD 值(比如g )与count[g]的总和是所有形成的序列的 GCD 之和。
下面是上述方法的实现:
C++
// C++ implementation of the above approach
#include
using namespace std;
const int MOD = (int)1e9 + 7;
// Function to find a^b in log(b)
int fastexpo(int a, int b)
{
int res = 1;
a %= MOD;
while (b) {
if (b & 1)
res = (res * a) % MOD;
a *= a;
a %= MOD;
b >>= 1;
}
return res;
}
// Function that finds the sum of GCD
// of all the subsequence of N length
int sumofGCD(int n, int k)
{
// To stores the number of sequences
// with gcd i
int count[k + 1] = { 0 };
// Find contribution of each gcd
// to happen
for (int g = k; g >= 1; g--) {
// To count multiples
int count_multiples = k / g;
// possible sequences with
// overcounting
int temp;
temp = fastexpo(count_multiples, n);
// to avoid overflow
temp %= MOD;
// Find extra element which will
// not form gcd = i
int extra = 0;
// Find overcounting
for (int j = g * 2; j <= k; j += g) {
extra = (extra + count[j]);
extra %= MOD;
}
// Remove the overcounting
count[g] = (temp - extra + MOD);
count[g] %= MOD;
}
// To store the final answer
int sum = 0;
int add;
for (int i = 1; i <= k; ++i) {
add = (count[i] % MOD * i % MOD);
add %= MOD;
sum += add;
sum %= MOD;
}
// Return Final answer
return sum;
}
// Driver Code
int main()
{
int N = 3, K = 2;
// Function call
cout << sumofGCD(N, K);
return 0;
}
Java
// Java implementation of the above approach
class GFG{
static int MOD = (int)1e9 + 7;
// Function to find a^b in log(b)
static int fastexpo(int a, int b)
{
int res = 1;
a %= MOD;
while (b > 0) {
if (b % 2 == 1)
res = (res * a) % MOD;
a *= a;
a %= MOD;
b >>= 1;
}
return res;
}
// Function that finds the sum of GCD
// of all the subsequence of N length
static int sumofGCD(int n, int k)
{
// To stores the number of sequences
// with gcd i
int []count = new int[k + 1];
// Find contribution of each gcd
// to happen
for (int g = k; g >= 1; g--) {
// To count multiples
int count_multiples = k / g;
// possible sequences with
// overcounting
int temp;
temp = fastexpo(count_multiples, n);
// to astatic void overflow
temp %= MOD;
// Find extra element which will
// not form gcd = i
int extra = 0;
// Find overcounting
for (int j = g * 2; j <= k; j += g) {
extra = (extra + count[j]);
extra %= MOD;
}
// Remove the overcounting
count[g] = (temp - extra + MOD);
count[g] %= MOD;
}
// To store the final answer
int sum = 0;
int add;
for (int i = 1; i <= k; ++i) {
add = (count[i] % MOD * i % MOD);
add %= MOD;
sum += add;
sum %= MOD;
}
// Return Final answer
return sum;
}
// Driver Code
public static void main(String[] args)
{
int N = 3, K = 2;
// Function call
System.out.print(sumofGCD(N, K));
}
}
// This code is contributed by PrinciRaj1992
蟒蛇3
# Python3 implementation of the above approach
MOD = (int)(1e9 + 7)
# Function to find a^b in log(b)
def fastexpo(a, b) :
res = 1
a = a % MOD
while (b > 0) :
if ((b & 1) != 0) :
res = (res * a) % MOD
a = a * a
a = a % MOD
b = b >> 1
return res
# Function that finds the sum of GCD
# of all the subsequence of N length
def sumofGCD(n, k) :
# To stores the number of sequences
# with gcd i
count = [0] * (k + 1)
# Find contribution of each gcd
# to happen
for g in range(k, 0, -1) :
# To count multiples
count_multiples = k // g
# possible sequences with
# overcounting
temp = fastexpo(count_multiples, n)
# to avoid overflow
temp = temp % MOD
# Find extra element which will
# not form gcd = i
extra = 0
# Find overcounting
for j in range(g * 2, k + 1, g) :
extra = extra + count[j]
extra = extra % MOD
# Remove the overcounting
count[g] = temp - extra + MOD
count[g] = count[g] % MOD
# To store the final answer
Sum = 0
for i in range(1, k + 1) :
add = count[i] % MOD * i % MOD
add = add % MOD
Sum = Sum + add
Sum = Sum % MOD
# Return Final answer
return Sum
# Driver code
N, K = 3, 2
# Function call
print(sumofGCD(N, K))
# This code is contributed by divyeshrabadiya07.
C#
// C# implementation of the above approach
using System;
class GFG{
static int MOD = (int)1e9 + 7;
// Function to find a^b in log(b)
static int fastexpo(int a, int b)
{
int res = 1;
a %= MOD;
while (b > 0) {
if (b % 2 == 1)
res = (res * a) % MOD;
a *= a;
a %= MOD;
b >>= 1;
}
return res;
}
// Function that finds the sum of GCD
// of all the subsequence of N length
static int sumofGCD(int n, int k)
{
// To stores the number of sequences
// with gcd i
int []count = new int[k + 1];
// Find contribution of each gcd
// to happen
for (int g = k; g >= 1; g--) {
// To count multiples
int count_multiples = k / g;
// possible sequences with
// overcounting
int temp;
temp = fastexpo(count_multiples, n);
// to astatic void overflow
temp %= MOD;
// Find extra element which will
// not form gcd = i
int extra = 0;
// Find overcounting
for (int j = g * 2; j <= k; j += g) {
extra = (extra + count[j]);
extra %= MOD;
}
// Remove the overcounting
count[g] = (temp - extra + MOD);
count[g] %= MOD;
}
// To store the readonly answer
int sum = 0;
int add;
for (int i = 1; i <= k; ++i) {
add = (count[i] % MOD * i % MOD);
add %= MOD;
sum += add;
sum %= MOD;
}
// Return Final answer
return sum;
}
// Driver Code
public static void Main(String[] args)
{
int N = 3, K = 2;
// Function call
Console.Write(sumofGCD(N, K));
}
}
// This code is contributed by Princi Singh
Javascript
输出:
9
时间复杂度: O( K*log(N) + K*log(log(K)) )