https://vjudge.net/problem/HDU-2973
威尔逊定理:若p为质数,p | (p-1)! + 1,即 (p-1)! = p - 1 = -1 (mod p)
根据题意,Sn = f(1) + f(2) + ... + f(k)
若(3 * k + 7)为质数,f(k) = 1。
若(3 * k + 7)不为质数,f(k) = 0。
求f(x)前缀和即可得Sn
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
const int maxn = 3e6 + 20;
bool isprime[maxn];
int prime[maxn / 10],sz =0 ;
int cnt[maxn / 3];
void init()
{
for (int i = 2; i < maxn; i ++) {
if(!isprime[i]) prime[sz ++] = i;
for (int j = 0; j < sz && (ll)prime[j] * i < maxn; j ++) {
isprime[prime[j] * i]= 1;
if(i % prime[j] == 0) break;
}
}
int k = 10;
for (int i = 1; k < maxn; i ++) {
if(!isprime[k]) cnt[i] ++;
k += 3;
}
for (int i = 2; i < maxn / 3; i ++) {
cnt[i] += cnt[i - 1];
}
}
int main()
{
init();
int T;scanf("%d",&T);
int n;
while (T --) {
scanf("%d",&n);
printf("%d\n",cnt[n]);
}
return 0;
}