• bzoj 2818: Gcd 歐拉函數


    2818: Gcd

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 1633  Solved: 724
    [Submit][Status]

    Description

    给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
    数对(x,y)有多少对.

    Input

    一个整数N

    Output

    如题

    Sample Input

    4

    Sample Output

    4

    HINT

    hint

    对于样例(2,2),(2,4),(3,3),(4,2)


    1<=N<=10^7

    Source

    求gcd(x,y)==prime[k] 對數(1<=x,y<=n)

    枚舉質數p,求gcd(x,y)==1, (1<=x,y<=n/p)

    設sphi(k)表示gcd(x,y)==1,(1<=x,y<=k),那麼,可以通過幾何法推導出sphi(k)=phi(k)*2+sphi(k-1)

    然後此題可解。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<string>
    #include<queue>
    using namespace std;
    #ifdef WIN32
    #define LL "%I64d"
    #else
    #define LL "%lld"
    #endif
    #define MAXN 11000000
    #define MAXV MAXN*2
    #define MAXE MAXV*2
    #define INF 0x3f3f3f3f
    #define INFL 0x3f3f3f3f3f3f3f3fLL
    typedef long long qword;
    inline int nextInt()
    {
            char ch;
            int x=0;
            bool flag=false;
            do
                    ch=getchar(),flag=(ch=='-')?true:flag;
            while(ch<'0'||ch>'9');
            do x=x*10+ch-'0';
            while (ch=getchar(),ch<='9' && ch>='0');
            return x*(flag?-1:1);
    }
    
    int n,m;
    bool pflag[MAXN];
    int prime[MAXN],topp=-1;;
    int phi[MAXN];
    void init()
    {
            int i,j,k;
            int x,y;
            phi[1]=1;
            for (i=2;i<MAXN;i++)
            {
                    if (!pflag[i])
                    {
                            prime[++topp]=i;
                            phi[i]=i-1;
                    }
                    for (j=0;j<=topp && i*prime[j]<MAXN;j++)
                    {
                            pflag[i*prime[j]]=true;
                            phi[i*prime[j]]=phi[i]*phi[prime[j]];
                            if (i%prime[j]==0)
                            {
                                    x=i;y=prime[j];
                                    k=1;
                                    while (x%prime[j]==0)
                                    {
                                            x/=prime[j];
                                            y*=prime[j];
                                            k++;
                                    }
                                    if (x==1)
                                    {
                                            phi[i*prime[j]]=y-y/prime[j];
                                    }else
                                    {
                                            phi[i*prime[j]]=phi[x]*phi[y];
                                    }
                                    break;
                            }
                    }
            }
    }
    qword sphi[MAXN];
    int main()
    {
            freopen("input.txt","r",stdin);
            int i,j,k;
            init();
            scanf("%d",&n);
            qword ans=0;
            sphi[1]=1;
            for (i=2;i<=n;i++)
                    sphi[i]=sphi[i-1]+phi[i]*2;
            for (i=0;i<=topp && prime[i]<=n;i++)
            {
                    ans+=sphi[n/prime[i]];
            }
            printf(LL"
    ",ans);
    }
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    如何创建不可变的Java类或对象
    Java动态代理
    Java序列化和克隆
    关于 Java高新技术的一些认识
    利用Servlet在客户端输出PDF文件
    学好Java语言的几大要点
    父进程结束子进程怎么办?
    wait/waitpid
    速记
    pip使用镜像的方法
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4007281.html
Copyright © 2020-2023  润新知