题意:
给出自然数 n,计算出 S的值,其中 [ x ]表示不大于 x 的最大整数。
题解:
根据威尔逊定理,如果 p 为素数,那么 (p-1)! ≡ -1(mod p),即 (p-1)! + 1 = p*q.
令 f(K) =
①如果 3K+7 为素数,则 (3K+7-1)! ≡ -1(mod 3K+7),即 (3K+6)! = (3K+7)*q -1.
那么表达式 可化简为 [ (3K+7)*q / (3K+7) - 1 / (3K+7) ] = [ q - 1 / (3K+7)].
易得 q-1 < q - 1 / (3K+7) < q ,所以=q-1,那么 f(K)= q-(q-1) = 1.
②如果 3K+7 为合数,则 (3K+6)! 能被 (3K+7) 整除,f(K) = 0;
由此,本题转化为求解K在[1,n]范围内 (3K+7) 的素数个数。
对②的证明:
令p=a*b,(<a<=b)
①若a!=b,则(p-)!=**..*a*..*b*..*(p-),显然 (a*b) | (p-)!;
②若a==b且为素数,则当a>2时,a*b=a*a>*a,
若p>,则(p-)! = **..*a*..*(2a)*..(p-),同样有(a*b)|(p-)!;
综上,如果p为合数,则 p | (p-)!;
AC代码:
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=1e6+; int n;
int ans[maxn];//ans[i]:[1,i]中,满足 3K+7 为素数的整数个数 bool isPrime(int num)
{
int x=sqrt(num);
for(int i=;i <= x;++i)
if(num%i == )
return ;
return ;
}
void primeTable()
{
ans[]=;
for(int i=;i < maxn;++i)//离散计算出所有的结果
ans[i]=ans[i-]+isPrime(*i+);
}
int main()
{
int test;
scanf("%d",&test);
primeTable();
while(test--)
{
scanf("%d",&n);
printf("%d\n",ans[n]);
}
return ;
}