• BZOJ2818 欧拉函数


    题意:求1--n中满足gcd(x,y)的值为质数的数对(x,y)的数目  ( (x,y)和(y,x)算两个 )

    sol:

    设p[i]是一个质数,那么以下两个命题是等价的:

    1.gcd(x,y)=1

    2.gcd(x*p[i],y*p[i])=p[i]

    eg:gcd(36,25)=1,gcd(36*7,25*7)=7

    所以对于1--n的所有质数p[i],求一下1<=x,y<=n/p[i]中所有gcd(x,y)=1的数对的数目即可。

    如何求1--r范围内所有互质数对的数目?

    考虑欧拉函数φ(x)=1..x中与x互质的数的数目

    设x<=y,那么这样就可以求出来了:

    for y:=2 to r do    //1不是质数也不是合数,而且1和任意数的gcd都等于1,应该除去
      ans+=2*phi[y];           //(x,y)和(y,x)算两个
    ans++;    //这是本题的特殊情况:当x==y时,gcd(y,y)的值也是质数

    Solve函数是题解里用的,事先累加了所有2*phi[i],速度要快一点点

    Reference: http://blog.csdn.net/acdreamers/article/details/8542292

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cmath>
     4 using namespace std;
     5 #define LL long long
     6 #define MMX 10000010
     7 int phi[MMX],p[MMX];
     8 LL psum[MMX];
     9 bool pr[MMX];
    10 LL nm,ret,n;
    11 
    12 void calc_phi(int n)        //求1--n的欧拉函数,phi[i]
    13 {                           //psum[n]:sum of phi[1..n]*2
    14     for (int i=2;i<=n;i++)
    15         phi[i]=0;
    16     phi[1]=1;
    17     for (int i=2;i<=n;i++)
    18         if (!phi[i])
    19             for (int j=i;j<=n;j+=i)
    20             {
    21                 if (!phi[j])    phi[j]=j;
    22                 phi[j]=phi[j]/i*(i-1);
    23             }
    24     psum[1]=0;
    25     for (int i=2;i<=n;i++)
    26         psum[i]=psum[i-1]+phi[i]*2;
    27 }
    28 
    29 void isprime(LL n)     //求1--n的质数。pr[i]=1 : i is a prime
    30 {
    31     nm=0;
    32     memset(pr,true,sizeof(pr));
    33     LL m=sqrt(n+0.5);
    34     pr[1]=false;
    35     for (LL i=2;i<=m;i++)
    36         if (pr[i])
    37         {
    38             for (LL j=i*i;j<=n;j+=i)
    39                 pr[j]=false;
    40         }
    41     for (int i=1;i<=n;i++)
    42         if (pr[i])
    43         {
    44             nm++;
    45             p[nm]=i;
    46         }
    47 }
    48 
    49 LL Solve(int n)     //
    50 {
    51     LL ans = 0;
    52     for(int i=1; i<=nm&&p[i]<=n; i++)
    53         ans += 1 + psum[n/p[i]];
    54     return ans;
    55 }
    56 
    57 int main()
    58 {
    59     cin>>n;
    60     isprime(n);
    61     calc_phi(n);
    62 
    63     LL ret=0;
    64     for (int i=1;i<=nm;i++)
    65     {
    66         int r=n/p[i];
    67         for (int j=2;j<=r;j++)  //注意1不能包括进去,因为gcd(1,?)恒等于1
    68             ret+=2*phi[j];
    69         ret++;
    70     }
    71     cout<<ret<<endl;
    72 
    73     //cout<<endl<<Solve(n)<<endl;
    74     return 0;
    75 }
  • 相关阅读:
    HTTP请求报文与响应报文
    RTTI (Run-time type information) in C++
    Advanced C++ | Virtual Copy Constructor
    Virtual Destructor
    Advanced C++ | Virtual Constructor
    What happens when more restrictive access is given to a derived class method in C++?
    Can static functions be virtual in C++?
    Virtual functions in derived classes
    Default arguments and virtual function
    Multiple Inheritance in C++
  • 原文地址:https://www.cnblogs.com/pdev/p/4095085.html
Copyright © 2020-2023  润新知