GCD and LCM HDU

来源:互联网 发布:javascript例子 编辑:程序博客网 时间:2024/06/04 23:32

题意:已知l,g其中g=gcd(x,y,z),l=lcm(x,y,z),问x,y,z有多少种组合使得关系成立。

思路:考虑唯一分解定理,对任意一个素因子,设其在g和l中的指数分别为a,b,则必有a <= b,且x,y,z中必有一个数指数为a,一个为b,至于另一个数其指数在a和b之间都行,所以有p(3,2)*(b-a-1)+3!/2!+3!/2!=6*(b-a).

可以将l/g,然后算各个素因子,也可以算出各个素因子的指数求出,最后再统一计算。

#include <iostream>  #include <cstdio>  #include <bitset>  #include <cstring>  #include <algorithm>  #include <vector>  #include <map>  #include <cmath>  #include <set>  #include <queue>  using namespace std;  typedef long long ll;    const int INF=1e9+100;     const int mod=1e9+7;int fac1[50005],fac2[50005];bool isprime[1000005];//用true表示i是素数  int prime[1000005],p;//第i个素数  void get_prime(int n){      p=0;      for(int i=0;i<=n;i++) isprime[i]=true;      isprime[0]=isprime[1]=false;      for(int i=2;i<=n;i++){          if(isprime[i]){              prime[p++]=i;              for(int j=2*i;j<=n;j+=i) isprime[j]=false;          }      }  }  int main(){    //freopen("out.txt","w",stdout);      int n,m,t;    get_prime(1000000);    scanf("%d",&t);    while(t--){        memset(fac1,0,sizeof(fac1));        memset(fac2,0,sizeof(fac2));        scanf("%d %d",&n,&m);        if(m%n){            printf("%d\n",0 );            continue;        }        m/=n;        int ans=1;        for(int i=0;i<p;i++){            int cnt=0;            while(m%prime[i]==0){            //printf("%d \n",prime[i] );                m/=prime[i];                cnt++;            }            if(cnt!=0)            ans*=6*cnt;            if(m==1) break;        }        if(m>1) ans*=6;        printf("%d\n",ans);    }    return 0;}

#include <iostream>  #include <cstdio>  #include <bitset>  #include <cstring>  #include <algorithm>  #include <vector>  #include <map>  #include <cmath>  #include <set>  #include <queue>  using namespace std;  typedef long long ll;    const int INF=1e9+100;     const int mod=1e9+7;int fac1[500005],fac2[500005];bool isprime[500005];//用true表示i是素数  int prime[500005],p;//第i个素数  void get_prime(int n){      p=0;      for(int i=0;i<=n;i++) isprime[i]=true;      isprime[0]=isprime[1]=false;      for(int i=2;i<=n;i++){          if(isprime[i]){              prime[p++]=i;              for(int j=2*i;j<=n;j+=i) isprime[j]=false;          }      }  }  void solve(int *a,int x){    for(int i=0;i<p;i++){        while(x%prime[i]==0){            x/=prime[i];            a[i]++;        }        if(x==1) break;    }    if(x>1) a[p]=x;}int main(){    //freopen("out.txt","w",stdout);      int n,m,t;    get_prime(500002);    scanf("%d",&t);    while(t--){        memset(fac1,0,sizeof(fac1));        memset(fac2,0,sizeof(fac2));        scanf("%d %d",&n,&m);        if(m%n){            printf("%d\n",0 );            continue;        }        solve(fac1,n);        solve(fac2,m);        int ans=1;        for(int i=0;i<p;i++){            if(fac2[i]-fac1[i]!=0)            ans*=6*(fac2[i]-fac1[i]);        }        if(fac1[p]!=fac2[p])            ans*=6;        printf("%d\n",ans);    }    return 0;}