Let m = 3k + 7. Then the given expression can be rewritten in the form:
Wilson's Theorem. If is a prime number, then
That is,
Therefore, if is prime, the number \frac{(m-1)!+1}{m} is an integer.
At the same time,
Then the entire expression equals
If is a composite number, then
because among its factors there are all the divisors of .
In this case, the number
is an integer.
Then the entire expression equals
Therefore, to compute S_n, it is enough to count the number of prime numbers of the form 3k + 7 for 1 \le k \le n.
Using the Sieve of Eratosthenes, we build the array , where:
Then, using the array , construct the array , which stores information about prime numbers of the form 3i + 7:
Now
Since the problem contains many test cases, to answer each in constant time, we build the prefix sums:
Now, to solve the problem for any given value of , it is enough to print .
Example
Let m = 7 be a prime number. Then
Let m = 6 be a composite number. Then
Let's compute the answer for n = 10. Consider all numbers of the form 3k + 7, where 1 \le k \le 10. Among them, identify the prime numbers.
Among the listed numbers, there are prime numbers: and . Therefore, S_{10} = 4.
Algorithm implementation
Let us declare the arrays. Since n \le 10^6, the size of the arrays should be set to 3n + 7 = 3 \cdot 10^6 + 7.
#define MAX 3000010
char used[MAX], a[MAX];The function Init implements the Sieve of Eratosthenes. The array stores information about prime numbers:
The array stores information about prime numbers of the form 3i + 7:
void Init()
{
for (int i = 2; i < MAX; i++)
{
if (!used[i])
{
if ((i - 7) % 3 == 0)
a[(i - 7) / 3] = true;
if (i < sqrt(MAX))
for (int j = i * i; j < MAX; j += i)
used[j] = true;
}
}
}The main part of the program. Fill the arrays.
Init();Compute the prefix sums for the array :
for (int i = 2; i < MAX; ++i)
p[i] = p[i - 1] + a[i];Process the tests sequentially.
scanf("%d", &tests);
while (tests--)
{
scanf("%d", &n);For each value of print .
printf("%d\n", p[n]);
}