题目:http://poj.org/problem?id=2478
思路:鸣谢某大神QAQ
[这里是链接君]http://blog.csdn.net/u014733623/article/details/24022179
所谓欧拉公式就是对一个数j求有多少个比j小,且与j互斥的数(互斥即为最大公约数为1),比如4,这个数,满足该要求的为1、3两个数,8这个满足的为1、3、5、7四个数。欧拉公式的算法是对于一个数j,满足该要求的数的个数为——所有能够把它整除的素数k,d[j]=d[j]/k*(k-1)。比如8这个数只能被2这一素数整除,那么满足要求的个数为8/2*(2-1)=4个,再比如6,它可以被素数2和3整除,那么个数为6/2*(2-1)=3 再 3/3*(3-1)=2 共有两个数(1和5这两个数)。
AC代码://QAQ我也不造为什么代码那么复杂...
//MEMORY 13116K TIME 125MS
//一开始觉得求素数的size只需要开到500000就可以了因为必须是质数的二倍才可以被计算但是WA了。
//觉得这道题似乎不用欧拉公式也可以?QAQ明天试一下好了...因为要做课设了...
//这里记录一下欧拉公式的算法是对于一个数j,所有能够把它整除的素数k,d[j]=d[j]/k*(k-1)。
#include<cstdio>
#include<cstring>
using namespace std;
#define size 1000010
int n,m,i,j;
long long res,ans;
bool judge[size];
int num[1000010];
long long s[1000010];
void init()
{
memset(judge,true,sizeof(judge));
for(i=2; i<size; i++)
{
if(judge[i])
for(j=2; i*j<size; j++)
judge[i*j]=false;
}
for(i=1;i<1000010;i++)num[i]=i;
for(i=2;i<size;i++){
if(judge[i]){
num[i]--;//因为如果它本身是质数的话,计数的时候要少计算一个。就是减掉它本身啦。
for(j=2;i*j<1000010;j++)
num[i*j]=num[i*j]/i*(i-1);
}
}
s[2]=num[2];
for(i=3;i<1000010;i++)
s[i]=s[i-1]+num[i];
}
int main()
{
init();
while(scanf("%d",&n)!=EOF){
if(n!=0)
printf("%lld\n",s[n]);
}
}
于是不用欧拉公式果然是错误的QAQ...【或者说目前没想到正确的做法QAQ...