HDU 4497(素数分解+排列组合)

来源:互联网 发布:淘宝店铺怎么添加音乐 编辑:程序博客网 时间:2024/06/09 22:35

hdu 4497
题目大意:
已知gcd(x,y,z)=G,lcm(x,y,z)=L;求这样的x, y, z有几种,其中(1,2,3)(3,2,1) 算两种;
思路:
因式分解
G=ap11ap22...apkk;
L=aq11aq22...aqss(qi>pi)
L%G!=0,ans=0;
m=L/G=br11br22...brtt;
X=x/G=bn11bn22...bntt;
同理: Y=i=1tbmii,Z=i=1tboii,
min(ni,mi,oi)=0,max(ni,mi,oi)=ri,且X,Y,Z中对因子bi,必定为(0,ri,0ri),即一个一定为0个,一个为ri个,一个为0ri个;
(0,0,ri)  3种;
(0,ri,ri)  3种;
(0,ri,1ri1)  6种;
即每个因子共有6ri种排列;

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#define N 200005using namespace std;bool not_prime[N];int prim[N];void init(){    memset(not_prime, 0, sizeof(not_prime));    prim[1] = 0;    int cnt = 0;    for(int i = 2; i < N; i++)     {          if(!not_prime[i])         {               prim[cnt++] = i;            for(int j = i + i; j < N; j += i)            {                  not_prime[j] = 1;              }          }      }  }void get(int m){    int ans = 1;    for (int i = 0; prim[i] * prim[i] <= m; i++)    {        if (m % prim[i] == 0)        {            int cnt = 0;            while (m % prim[i] == 0)            {                cnt++;                m /= prim[i];            }             ans *= 6 * cnt;        }    }    if (m > 1)    {        ans *= 6;    }    printf("%d\n", ans);}int main(){    init();    int T;    scanf("%d", &T);    while (T--)    {        int gcd, lcm;        scanf("%d%d", &gcd, &lcm);        if (lcm % gcd != 0)        {            printf("0\n");            continue;        }        int m = lcm / gcd;        get(m);    }    return 0;}
0 0