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

原文地址:https://www.cnblogs.com/mhy12345/p/4007281.html