Arce 发表于 2021-7-11 12:23:58

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={0};
prime=2;
for(i=3;i<=46341;i+=2)
{
if(Prime(i)==1)
prime=i;
}
while((scanf("%lld",&n))!=EOF)
{
if(n==1)
printf("0\n");
else
{
temp=n;
phi=1;
i=0;
while(prime!=0)
{
if(n==1)
break;
flag=0;
while(n%prime==0)
{
flag=1;
phi=phi*prime;
n/=prime;
}
if(flag==1)
phi=(phi*(prime-1))/prime;
i++;
}
if(n>1)
phi=phi*(n-1);
printf("%lld\n",temp-phi);
}
}
return 0;
}

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

#include<stdio.h>
int Eular(intn){
   int i;
   intans=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;
}        

  

  
文档来源:51CTO技术博客https://blog.51cto.com/liulizhi1996/3035752
页: [1]
查看完整版本: NYOJ 570 解题报告