HDU 4983 Goffi and GCD(数列、欧拉函数)

来源:互联网 发布:python 网管snmp 编辑:程序博客网 时间:2024/05/23 16:36

Goffi and GCD

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 729    Accepted Submission(s): 248


Problem Description
Goffi is doing his math homework and he finds an equality on his text book: gcd(na,n)×gcd(nb,n)=nk.

Goffi wants to know the number of (a,b) satisfy the equality, if n and k are given and 1a,bn.

Note: gcd(a,b) means greatest common divisor of a and b.
 

Input
Input contains multiple test cases (less than 100). For each test case, there's one line containing two integers n and k (1n,k109).
 

Output
For each test case, output a single integer indicating the number of (a,b) modulo 109+7.
 

Sample Input
2 13 2
 

Sample Output
21
Hint
For the first case, (2, 1) and (1, 2) satisfy the equality.
 

Source
BestCoder Round #6
 


题目大意:给出一组n和k,求解满足公式:gcd(n-a,n)*gcd(n-b,n)=n^k的(a,b)的对数,结果对(1e9+7)取模。


先证明:对于1<=x<=n,有gcd(n-x , n) = gcd(x , n) 。

假设gcd(n-a , n) = x(1<=a<=n),则x是(n-a)和n的最大公约数,所以存在整数k1,k2(并且k1<k2,而且

gcd(k1,k2)=1即k1和k2没有除1以外的公约数)使得n-a=k1*x,n=k2*x;那么a=n-k1*x=k2*x-k1*x=(k2-k1)*x,则

gcd(a,n)=gcd((k2-k1)*x,n)=gcd((k2-k1)*x,k2*x)。那么gcd((k2-k1)*x,k2*x)是否等于x呢???

因为k1与k2没有除1以外的公约数,所以对任意的i(i>1)都有k2!=k1*i,则(k2-k1)与k2没有除1以外的公约数。

所以gcd(a,n)=gcd((k2-k1)*x,k2*x)=x=gcd(n-a , n),同理gcd(b,n)=gcd(n-b,n)



解题思路:gcd(n-a,n)*gcd(n-b,n)=n^k可以化为gcd(a,n)*gcd(b,n)=n^k。

对于任意的gcd(x,y)<=max(x,y),则对于公式:gcd(a,n)*gcd(b,n)=n^k,

因为1<=a,b<=n,所有我们有gcd(a,n)<=n,gcd(b,n)<=n。所以gcd(a,n)*gcd(b,n)<=n^2,

当n=1时,原公式只有1解;

当k>2时,原公式无解;

当k=2时,只有a=b=n时,gcd(a,n)=n,gcd(b,n)=n,gcd(a,n)*gcd(b,n)=n^2,即原公式只有1解;

当k=1时,就是求gcd(a,n)*gcd(b,n)=n,如果gcd(a,n)=x,则gcd(b,n)=n/x,这里只要枚举x,求n/x即可。x是a和n的最

大公约数,那么x就是n的因数,因此枚举n的因数就可以了。对于每一个x可能会有多个a(1<=a<=n)存在,使得

gcd(a,n)=x,假设存在ma个;那么对于每一个n/x,同样会有多个b(1<=b<=n)存在,使得gcd(b,n)=n/x,假设存在

mb个(对于ma,mb的求解可以用欧拉函数求解?????)。那么对于一个x,如果x*x!=n,那么就存在2*ma*mb

对结果,如果x*x==n,那么就存在ma*mb对结果


代码如下:

#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <ctime>#include <iostream>#include <algorithm>#include <string>#include <vector>#include <deque>#include <list>#include <set>#include <map>#include <stack>#include <queue>#include <numeric>#include <iomanip>#include <bitset>#include <sstream>#include <fstream>#include <limits.h>#define debug "output for debug\n"#define pi (acos(-1.0))#define eps (1e-6)#define inf (1<<28)#define sqr(x) (x) * (x)#define mod 1000000007using namespace std;typedef long long LL;typedef unsigned long long ULL;long long n,k;//欧拉函数long long euler(long long x){    long long i,res=x;    for(i=2;i*i<=x;i++)    {        if(x%i==0)        {            res=res/i*(i-1);            while(x%i==0)                x=x/i;        }    }    if(x>1)        res=res/x*(x-1);    return res;}int main(){    long long i,sum;    while(scanf("%I64d%I64d",&n,&k)!=EOF)    {        if(n==1)//        {            printf("1\n");            continue;        }        if(k>2)//        {            printf("0\n");            continue;        }        if(k==2)//        {            printf("1\n");        }        else//当k=1时        {           sum=0;           //枚举n的因数            for(i=1;i*i<=n;i++)            {                if(n%i==0)                {                    if(i*i==n)//                        sum+=euler(n/i)*euler(i);                    else//                        sum+=2*euler(n/i)*euler(i);                    sum%=mod;                }            }            printf("%I64d\n",sum);       }    }    return 0;}




0 0
原创粉丝点击