欧拉函数 POJ2480

来源:互联网 发布:淘宝女包店 我爱你店 编辑:程序博客网 时间:2024/05/17 22:52

https://vj.xtuacm.cf/contest/view.action?cid=57#problem/Q
这题中求欧拉数的方式很好

思路:首先假设n有一个约数d,那么怎样计算出1~n中最大公约数为d的个数呢?很显然,这个个数实质上是等于fin(n/d)(其中先用fin代表欧拉函数),想到这里的话,基本上就确定了策略,我们先枚举出n的所有约数,然后求出每一个的欧拉函数,然后d*fin(n/d)相加后的结果即为所求

#include <iostream>#include <cstdio>#include <algorithm>#define ll long longusing namespace std;int a[100000],cnt;ll euler(ll n){    ll ans=1;    for(ll i=2; i*i<=n; i++)    {        if(n%i)            continue;        ans*=i-1;        n=n/i;        while(n%i==0)        {            n=n/i;            ans*=i;        }    }    if(n>1)ans*=(n-1);    return ans;}void fen(ll n){    ll i;    for( i=1; i*i<n; i++)//在这里注意要用longlong 如果用int的话    {                    //会出现溢出,然后再次进行循环,导致超时        if(n%i==0)        {            a[cnt++]=i;            a[cnt++]=n/i;        }    }    if(i*i==n)        a[cnt++]=i;}int main(){    ll n;    while(~scanf("%I64d",&n))    {        cnt=0;        fen(n);        ll sum=0;        int i;        for( i=0; i<cnt; i++)        {            sum+=a[i]*euler(n/a[i]);        }        printf("%I64d\n",sum);    }    return 0;}
原创粉丝点击