[POJ2458]欧拉公式

题目: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...


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值