light oj 1341 唯一性分解【数论入门】

本文介绍了一种计算因子对数量的方法,利用唯一性分解定理计算第一个数的因子对,要求因子对中的任意两个数都必须大于第二个数。通过素数筛选和分解,实现了因子对的有效计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意就是:给你两个数,然后让你去求第一个数分解的因子对数,其中要求因子对中的任意两个数都必须大于第二个数,声明对于(2,6)和(6,2)是一个因子对。

分析:先利用唯一性分解的方法对第一个数进行分解,然后根据定理这个数的因子个数为(1+a1)(1+a2)。。。(1+an)然后再除以2得到因子对个数,再根据第二个数来减去相应的值。对于这道题主要是学习到了唯一性定理中关于因子个数的计算,这一点是我所不知道的,也是我感觉是这道题求解的重点,其次就是一些细节的处理,比如关于第二个数和第一个数关系的特判,以及我在素数筛选时,int的爆范围等等,都是以后应该注意到的地方。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
#include<cmath>

using namespace std;

typedef long long ll;
const int maxn = 1e6 + 10;
bool isprime[maxn];
ll prime[maxn], k;

void ini()
{
		memset(isprime, true, sizeof isprime);
		memset(prime, 0, sizeof prime);
}

void check()
{
		//isprime
		k = 0;
		int re = sqrt(maxn);
		for (int i = 2; i <maxn; i++)
		{
				if (isprime[i])
				{
						prime[k++] = i;
						for (long long j =(long long) i * i; j < maxn; j += i)  isprime[j] = false;
				}
		}
}

ll solve(ll num)
{
		ll sum = 1;
		for (int i = 0; i < k&&prime[i] * prime[i] <= num; i++)
		{
				if (num%prime[i] == 0)
				{
						ll ans = 0;
						while (num%prime[i] == 0)
						{
								ans++;
								num /= prime[i];
						}
						sum *= (1 + ans);
				}
		}
		if (num > 1)    sum *= 2;
		return sum;
}

int main()
{
		int t;
		scanf("%d", &t);
		ini();
		check();
		for (int i = 1; i <= t; i++)
		{
				ll area, a;
				scanf("%lld %lld", &area, &a);
				if (area < a*a)
				{
						printf("Case %d: 0\n", i);
						continue;
				}
				ll res = solve(area);
				res /= 2;
				for (int j = 1; j < a; j++)    if (area%j == 0)   res--;
				printf("Case %d: %lld\n", i, res);
		}
		//system("pause");
		return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值