[欧拉函数] hdu 4983 Goffi and GCD

来源:互联网 发布:天谕最萌玲珑捏脸数据 编辑:程序博客网 时间:2024/05/23 16:47

题目:给你N和K,问有多少个数对满足gcd(N-A,N)*gcd(N-B,N)=N^K

思路:首先如果K>2 显然是不可能有解的 那么输出0,如果k=2,那么只有(0,0)的答案,输出1

那么如果k=1,那么就是分解N 然后看组成这些因子的方法数。

比如N=10 那么因子有 1 2 5 10 显然就是两对,(1,10),(2,5)

然后就是分别找出组成1有多少种,10有多少种。然后2有几种,5有几种然后再乘2

那么具体是几种呢。

其实求2的话 就是不大于N/2与N/2互质的数的个数 也就是eular(N/2).

一次类推,但是注意比如4有一组(2,2) 那么这里就不能再乘2了 然后枚举就好了。

代码:

#include"cstdlib"#include"cstdio"#include"cstring"#include"cmath"#include"queue"#include"algorithm"#include"iostream"#include"map"using namespace std;int ans[123479];int m=1000000000+7;__int64 eular(int n){    __int64 ret=1,i;    for(i=2; i*i<=n; i++)    {        if(n%i==0)        {            n/=i,ret*=i-1;            while(n%i==0)                n/=i,ret*=i;        }    }    if(n>1)        ret*=n-1;    return ret;}int main(){    int n,k;    while(cin>>n>>k)    {        int i;        if(n==1)        {            puts("1");            continue;        }        if(k>=2)        {            if(k>2) puts("0");            else puts("1");            continue;        }        int cnt=0;        for(i=1; i<=sqrt(n*1.0); i++)        {            if(n%i==0) ans[cnt++]=i;        }        __int64 sum=0,x,y;        for(i=0;i<cnt;i++)        {            if(n/ans[i]==ans[i])            {                x=y=eular(n/ans[i]);                sum+=x*y;                sum%=m;            }            else            {                x=eular(n/ans[i]);                y=eular(ans[i]);                sum+=((x%m)*(y%m)*2)%m;                sum%=m;            }        }        printf("%I64d\n",sum%m);    }    return 0;}


                                             
0 0
原创粉丝点击