1. 程式人生 > >【ZCMU1796】wjw的數學題(唯一分解定理+排列組合)

【ZCMU1796】wjw的數學題(唯一分解定理+排列組合)

題目連結

1796: wjw的數學題

Time Limit: 2 Sec  Memory Limit: 128 MB
Submit: 70  Solved: 25
[Submit][Status][Web Board]

Description

Wjw recently encountered a mathematical problem .. given two positive integers x and y, how many kinds of schemes (a, b, c) make their gcd = x, lcm = y

 

Input

First line comes an integer T (T <= 12), telling the number of test cases.
The next T lines, each contains two positive  integers, x and y. The all input is guaranteed to be within the "int"

 

 

Output

For each test case, print one line with the number of solutions satisfying the conditions above.

 

Sample Input

2 6 72 7 33

Sample Output

72 0

HINT

 

Source

jnxxhzz

 

【題意】

求滿足最大公因數gcd(a,b,c)=x,最小公倍數lcm(a,b,c)=y的(a,b,c)的方案數。

【解題思路】

根據唯一分解定理,a,b,c可以被分解成質因數的乘積形式。

a=x1^a1*x2^a2*x3^a3……

b=x1^b1*x2^b2*x3^b3……

c=x1^c1*x2^c2*x3^c3……

那麼gcd(a,b,c)=min(a1,b1,c1)*min(a2,b2,c2)……      lcm(a,b,c)=max(a1,b1,c1)*max(a2,b2,c2)

所以3個數中必須保證每個數都有gcd,並且至少有一個數滿足max(a,b,c),所以其餘的部分就是由lcm/gcd裡面的質因子構成。所以Sample1中的72/6=12(12分解後為2 2 3),因為不同因子之間是不會相互干擾的(這點顯而易見吧...?),但是相同因子之間就要考慮干擾問題,比如3個位置都放有2的因子(先不考慮個數),那最終的gcd肯定就不是6了。並且為了滿足lcm,必須有一個位置是2的全部因子,有一個位置不能放2的因子,所以對於2這個因子要選擇兩個位置放置有3種情況(ab,bc,ac),然後這兩個位置的一個位置可以選擇放全部因子或者不放因子,那麼就是2*3=6種情況,另外一個位置可以選擇放0-cnt個因子,有cnt種可能(為什麼呢?n 0 n和n 0 0)。最後乘起來就是cnt*6啦。

【程式碼】

#include<bits/stdc++.h>
using namespace std;
const int maxn=50005;
int vis[maxn],cnt=0,prime[maxn];
void isprime()
{
    memset(vis,0,sizeof(vis));
	for(int i=2;i<maxn;i++)
	{
		if(!vis[i])prime[cnt++]=i;
		for(int j=0;j<cnt && i*prime[j]<maxn;j++)
		{
			vis[i*prime[j]]=1;
			if(i%prime[j]==0)break;
		}
	}
}
int main()
{
    int T;
    scanf("%d",&T);
    isprime();
    while(T--)
    {
        int x,y,ans=1;
        scanf("%d%d",&x,&y);
        if(y%x!=0)
        {
            printf("0\n");
            continue;
        }
        y/=x;
        for(int i=0;prime[i]<=y;i++)
        {
            if(y%prime[i]==0)
            {
                int cnt=0;
                while(y%prime[i]==0)
                {
                    y/=prime[i];
                    cnt++;
                }
                ans*=cnt*6;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}