欧拉函数模板题

来源:互联网 发布:jq 数组包含 编辑:程序博客网 时间:2024/06/06 15:35

点击打开链接

                                            欧拉

新年快到了,“猪头帮协会”准备搞一个聚会,已经知道现有会员N人,把会员从1到N编号,其中会长的号码是N号,凡是和会长是老朋友的,那么该会员的号码肯定和N有大于1的公约数,否则都是新朋友,现在会长想知道究竟有几个新朋友?请你编程序帮会长计算出来。

Input
第一行是测试数据的组数CN(Case number,1<CN<10000),接着有CN行正整数N(1<n<32768),表示会员人数。
Output
对于每一个N,输出一行新朋友的人数,这样共有CN行输出。
Sample Input
22560824027
Sample Output
768016016
题解:这题我看见最大公约数时候脑子里跳出来的是gcd,但是提交时候发现时间是超限的,gcd是不断的递归过程,消耗的时间较多,所以这题用欧拉函数···

下面这个是错的代码:

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<cstdlib>using namespace std;int gcd(int a,int b){if(b==0)return a;elsereturn gcd(b,a%b);}int main(){long long T;scanf("%lld",&T);while(T--){long long n,ans=0,i;scanf("%lld",&n);for( i=1;i<n;i++){if(gcd(n,i)>1)ans++;}printf("%lld\n",n-ans-1);}return 0;}


下面这个是ac过的代码:

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<cstdlib>using namespace std;long long  Eular(long long n)  {      int ans=1;      for (int i=2;i<=sqrt((double)n);i++)      {          if (n%i==0)          {              n/=i;              ans*=(i-1);              //若n有个因子是i的k次,根据欧拉公式有下面的代码              while (n%i==0)               {                  n/=i;                  ans*=i;              }          }      }      if (n>1)     //若最后剩的数为大于5的素数,根据欧拉公式再算进去           ans*=(n-1);      return ans;  }  int main(){long long T;scanf("%lld",&T);while(T--){long long n,ans=0,i;scanf("%lld",&n);printf("%lld\n",Eular(n));}return 0;}