GCD与LCM(hpu第八届校赛)

分析,一看我算了一下我的方法一定超时,然后就写了,果然超时了,然后我也想不出其他方法,然后我就搜了一下答案;

D=G+L;

x1=G*a;

x1=G*b;

因为G为x1,x2的最大公约数,所以a,b互质

D=G+G*a*b;

a*b=L/G=(D-G)/G=D/G-1;

单测试点时限: 2.0 秒

内存限制: 512 MB

Ocean某天遇到了一个很简单的数学题,但是他的大脑已经超负荷了。现在请你帮帮他吧:

已知D=GCD(x,y)+LCM(x,y),求合法组合(x,y)总数,其中x>0且y>0。

输入

第一行输入一个整数T,代表有T组测试数据。

接下来每行输入一个整数D。

注:1≤T,D≤105。

输出

对每组测试数据,输出一个整数代表可能出现的组合数。

样例

input

3
2
3
4

output

1
2
3

提示

GCD:最大公约数

LCM:最小公倍数

样例中:

若D=2,可能有①x=1,y=1

若D=3,可能有①x=1,y=2②x=2,y=1

若D=4,可能有①x=1,y=3②x=2,y=2③x=3,y=1

1 人解决,4 已尝试。

1 份提交通过,共有 7 份提交。

 #include<stdio.h>
#define maxn 100011
int num[maxn];
int gcd(int a,int b)
{
	return b==0?a:gcd(b,a%b);
}
void init()
{
	int i,j;
	num[1]=1;
	for(i=1;i*i<=maxn;i++)
	{
		for(j=i;i*j<=maxn;j++)
		{
			if(i==j) continue;
			if(gcd(i,j)==1)  num[i*j]+=2; //寻找互质的i*j    a*b=D/L-1;i*j相当于a*b; 
		}
	}
}
long long solve(int n)
{
	long long ans=0;
	int i;
	for(i=1;i*i<=n;i++)//这里i*i<=n 
	{
		if(n%i==0)//i相当于G;
		{
			ans+=num[n/i-1];//这个是大于sqrt(n)的 
			if(n/i!=i) ans+=num[i-1];//这个小于sqrt(n);
			//上面这两种情况优化到sqrt(n); 
		}
	}
	return ans;
}
int main()
{
	int T,n;
	init();
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		if(n==1) printf("0\n");
		else printf("%lld\n",solve(n));
	}
	return 0;
 } 

猜你喜欢

转载自blog.csdn.net/qq_42434171/article/details/85486744