其他分享
首页 > 其他分享> > NYOJ 570 解题报告

NYOJ 570 解题报告

作者:互联网

欧拉函数求和

时间限制: 1000 ms  |  内存限制: 65535 KB 难度: 3 描述

题目描述很简单,求出

(PS:上面式子的意思是大于0小于n并且能整除n的所有d的欧拉函数值之和)。

 

输入 每行一个数n(n<2^31),输入以文件结尾结束。 输出 每个结果占一行。 样例输入
1
2
12
样例输出
0
1
8

        这道题又是一道关于数论的题目。首先,我们需要知道,欧拉函数的和函数为,其中d包含1至n(含1和n),这和题目中的“和函数”不含有n是不同的。所以,。这里又要知道欧拉phi函数的计算公式,

        知道了这两个式子,这道题就没什么了~~~

        附上我的代码。

#include <stdio.h>
#include <math.h>

int Prime(long long n)
{
	long long i,flag=0;
	for(i=2;i<=(long long)sqrt(n);i++)
	{
		if(n%i==0)
		{
			flag=1;
			break;
		}
	}
	if(flag==0)
		return 1;
	else
		return 0;
}

int main()
{
	long long n,phi,flag,temp,i,j=0;
	long long prime[4800]={0};
	prime[j++]=2;
	for(i=3;i<=46341;i+=2)
	{
		if(Prime(i)==1)
			prime[j++]=i;
	}
	while((scanf("%lld",&n))!=EOF)
	{
		if(n==1)
			printf("0\n");
		else
		{
			temp=n;
			phi=1;
			i=0;
			while(prime[i]!=0)
			{
				if(n==1)
					break;
				flag=0;
				while(n%prime[i]==0)
				{
					flag=1;
					phi=phi*prime[i];
					n/=prime[i];
				}
				if(flag==1)
					phi=(phi*(prime[i]-1))/prime[i];
				i++;
			}
			if(n>1)
				phi=phi*(n-1);
			printf("%lld\n",temp-phi);
		}
	}
	return 0;
}

         标程里是直接硬算,从头遍历到尾。其实知道了第一个公式就不用这样了!

 
#include<stdio.h>
int Eular(int  n){
     int i;
     int  ans=n;
     for(i=2;i*i<=n;++i){
          if(n%i==0){
              ans-=ans/i;
                while(n%i==0)
			n=n/i;
                if(n==1)
			break;
          }
     }
     if(n!=1)
	 ans-=ans/n;
     return ans;
}
int main(){
    int i, j, k, n, x;
    while( ~scanf("%d",&n) ){
        int sum = 0;
        if(n==1){
            puts("0");
            continue;
        }
        for(i=1;i*i<=n;i++){
            if(n%i==0){
                sum+=(Eular(i));
                if( i!=1 && i*i!=n )
                    sum+=(Eular(n/i));
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}        




标签:phi,函数,int,570,NYOJ,long,解题,include,欧拉
来源: https://blog.51cto.com/liulizhi1996/3035752