GCD and LCM(数论)

VJ链接

题意:给出你两个数g和l。问有多少有序数组(x,y,z)满足gcd(x,y,z)=g,lcm(x,y,z)=l

思路:

1.对于(a,b,c),g和l必然存在l%g=0,因为三个数可以写成:a=x1gcd, b=x2gcd, c=x3gcd; l=ab*c/gcd; 显而易见,l%g=0若l%g!=0,不存在满足题意的情况。

2. 由于l%g==0,问题等价于求三个互质的数且LCM为l/g的所有情况数。

3.对2~n的数进行质因数分解,开一个数组存一下每个质因子的个数。对于:temp=l/g=p1 ^a1 * p2 ^a2 *p3 ^a3… * pn ^an

存在:

a=p1 ^ ai * p2 ^ ai *p3 ^ai… * pn ^ai
b=p1 ^ aj * p2 ^ aj *p3 ^aj… * pn ^aj
c=p1 ^ ak * p2 ^ ak *p3 ^ ak… * pn ^ak

最终推导规律:sum=a1 6a2 * 6 *…an * 6

代码:`

#include<stdio.h>
#include<string.h>
#define N 1000010
int a[N],k;
int main()
{
    int t,n,m;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        if(m%n){           //如果m%n!=0,数据不对         
            printf("0\n");
            continue;
        }
        int l=m/n,s=1,k=0;
        memset(a,0,sizeof(a));
        for(int i=2;i<=m/n;i++)
          if(l%i==0){
            while(l%i==0) 
              a[k]++,l/=i;   //记录质因子个数
              k++;
            }
        if(l>1) a[k++]++;  //剩余了一个质数       
        for(int i=0;i<k;i++)
            if(a[i])
              s*=a[i]*6; //推导的规律
        printf("%d\n",s);
    }
    return 0;
}

发布了85 篇原创文章 · 获赞 10 · 访问量 5253

猜你喜欢

转载自blog.csdn.net/riversuer/article/details/103412480