Table of Contents

ExplanationImplementation

Explanation

We can identify that given any integer cc, the number of integers that are divisible by it between 1 and NN is Nc\lfloor\frac{N}{c}\rfloor

If we consider each prime individually and find the number of multiples it has, we will find that there is an overlap for each number that is a multiple of two primes. For example, 1010 is a multiple of both 22 and 55, so if we added up all Na[i]\lfloor\frac{N}{a[i]}\rfloor for all primes, we would still need to subtract Na[i]a[j]\lfloor\frac{N}{a[i] \cdot a[j]}\rfloor for all distinct i and j.

Similarly, this subtraction would have an overlap for each number that is a multiple of three primes. An example would be 3030, a multiple of 22, 33, and 55, so we would have subtracted all multiples of both 66, 1010, and 1515, which would mean that we must add back the number of integers that are multiples of three primes. This extends for the entire array, requiring us to alternate adding and subtracting depending on how many primes we are currently multiplying.

Considering only 3030, the full example would be that our answer is added 33 times for 22, 33, and 55 (subsets of array with 11 prime), then subtracted 33 times for 66, 1010, and 1515 (subsets of array with 22 primes), and finally added once for 3030 (subset of array with 33 primes), overall only being counted once.

To implement this, we would need to go through each subset of the array, and add the number of multiples it has if the number of primes is not divisible by 2, and subtract otherwise. This is known as the Inclusion Exclusion Principle. In order to iterate through all subsets of the array, we can iterate from 11 to 2K12^K-1 and use bit operators to find which indices we are using.

Implementation

Time Complexity: O(K2K)\mathcal{O}(K\cdot 2^K)

C++

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
ll n, k;
cin >> n >> k;
vector<ll> a(k);
for (int i = 0; i < k; i++) cin >> a[i];

Java

import java.util.*;
public class PrimeMultiples {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long n = sc.nextLong();
int k = sc.nextInt();
long[] a = new long[k];
for (int i = 0; i < k; i++) { a[i] = sc.nextLong(); }

Python

Warning!

Due to Python's big constant factor, this code will TLE on a couple of test cases.

n, k = map(int, input().split())
a = list(map(int, input().split()))
ans = 0
for i in range(1, 1 << k):
prime_product = 1
for j in range(k):
# check if we are using a[j] in this number
if i & (1 << j):

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!