首页 > 代码库 > HDU4497 GCD and LCM 数论 素数分解

HDU4497 GCD and LCM 数论 素数分解

题意很简单首先以前做最简单的LCM跟CGD的时候都知道先求出两个数A,B的最大公约数GCD,那么LCM可以利用  A*B/GCD来求得,这点一开始脑残了没想到,结果没有进行特盘所以错了,意思就是 题目给的L%G不为0的话就是无解,结果我给判其它的去了,肯定漏了些什么没有发现


然后对于 L/G进行素因子分解,同时任意的数都能够通过素因子分解来表示,所以三个解x,y,z也能分解

L/G = p1^q1*p2^q2....

x = p1^i1*...

y = p1^j1*...

z = p1^k1*...

注意分解过后 咱们先忽略指数,保证x,y,z要互质同时这时候 LCM(x,y,z)的值为  L/G,那么我们只看第一个,对于素数p1来说,x,y,z中的p1的指数中肯定有一个为0,并且有另一个为q1,外加题目说打乱顺序的三个数算不同的 所以最后 排列一下就是六种


#include<iostream>
#include<cstdio>
#include<list>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<cmath>
#include<memory.h>
#include<set>
#include<cctype>

#define ll long long

#define LL __int64

#define eps 1e-8

#define inf 0xfffffff

//const LL INF = 1LL<<61;

using namespace std;

//vector<pair<int,int> > G;
//typedef pair<int,int > P;
//vector<pair<int,int> > ::iterator iter;
//
//map<ll,int >mp;
//map<ll,int >::iterator p;


#define N 100009

int prime[N];
bool isprime[N];
int k = 0;

void init()//依据题目数据范围处理一定范围内的素数
{
	memset(isprime,false,sizeof(isprime));
	for(int i=2;i<100009;i++)
		if(!isprime[i])
			for(int j=i*2;j<100009;j+=i)
				isprime[j]=true;
	k = 0;
	for(int i=2;i<100009;i++)
		if(!isprime[i])
			prime[k++]=i;
}

int main() {
	init();
	int G,L;
	int t;
	scanf("%d",&t);
	while(t--) {
		scanf("%d %d",&G,&L);
		if(L%G) {
			puts("0");//L肯定得是G的倍数,否则不存在答案,
			continue;
		}
		int tmp = L/G;
		int now = tmp;
		int ans = 1;
		for(int i=0;i<k;i++) {
			if(prime[i] * prime[i] > tmp)break;
			if(now%prime[i] == 0) {
				int cnt = 0;
				while(now%prime[i] == 0) {
					now /= prime[i];
					cnt++;
				}
				ans *= cnt * 6;
			}
		}
		if(now != 1) ans *= 6;
		printf("%d\n",ans);
	}
	return 0;
}