LightOJ - 1341 Aladdin and the Flying Carpet (唯一分解定理、求因数个数)

博客介绍了如何利用唯一分解定理解决LightOJ中1341题目的长方形面积问题。题目要求找到所有边长大于等于b的整数边长组合,构成给定面积a的长方形。博主指出,当前解决方案的时间复杂度过高,期待更优解法。文章详细阐述了如何计算一个数的因数个数,并预处理素数以加速计算。尽管存在b的限制导致无法避免线性遍历,但该问题依然能帮助学习者理解数论中的关键概念。
摘要由CSDN通过智能技术生成

LightOJ - 1341 Aladdin and the Flying Carpet (唯一分解定理、求因数个数)

题意:给一个 长方形 的面积a,求有多少组整数边可以构成这样的长方形,并且每一组边的最小长度不能小于b。

思路:我的这个复杂度理论上是不能过这一道题的!处理不符合要求的因数的复杂度太大了。但是我数论太菜了没有办法给出更优的解法,希望有个大佬能发一个正确复杂度的题解。但是这道题不妨碍学一下新的知识点。

我们可以知道一个数可以分解成若干个质数相乘,并且可能会有一些相同的质数在里面,表示为 x = p 1 a 1 + p 2 a 2 + . . . + p n a n x = p1^{a1}+p2^{a2}+...+pn^{an} x=p1a1+p2a2+...+pnan

那么唯一分解定理就可以得出x的因数的个数 f ( x ) = ( 1 + a 1 ) ∗ ( 1 + a 2 ) ∗ . . . ∗ ( 1 + a n ) f(x) = (1+a1)*(1+a2)*...*(1+an) f(x)=(1+a1)(1+a2)...(1+an)

对于这道题我们就可以预处理出前 1 e 6 1e6 1e6 个素数分别是多少(不需要再往上取了),然后针对于x把可以整除它的因数的指数求出来就可以得到x总共有多少个因数了,除以2就是没有限制的可以组成a的个数,但是现在有一个b的限制,在这里我就没有其他的好办法来减少时间了,只能 O ( n ) O(n) O(n) 地去遍历判断,可以整除一个就答案减一。

#include <bits/stdc++.h>
using namespace std;

int _;
long long a, b;

const int M = 1000000;
bool isprime[M+5];
int prime[M+5], cnt;

void solve() {
	for(int i = 1;i <= M; i++) isprime[i] = 1;
	for(int i = 3;i <= M; i++) if(!(i%2)) isprime[i] = 0;
	for(int i = 2;i <= M; i++) {
		if(isprime[i]) {
			for(int j = i*2; j<= M; j += i)
				isprime[j] = 0;
		}
	}
	isprime[1] = 0;
	for(int i = 2;i <= M; i++) {
		if(isprime[i]) prime[++cnt] = i;
	}
}

long long getfac(long long x) {
	long long ans=1;
	for(int i = 1;i <= cnt && prime[i] <= x; i++) {
		long long sum = 0;
		while(x%prime[i] == 0) {
			sum++;
			x /= prime[i];
		}
		ans *= (sum+1);
	}
	if(x>1) ans *= 2;
	return ans;
}

int main() {
	solve();
	int cas = 0;
	scanf("%d", &_);
	while(_--) {
		scanf("%lld %lld", &a, &b);
		printf("Case %d: ", ++cas);
		if(a < b*b) {puts("0"); continue;}
		long long ans = getfac(a);
		ans /= 2;
		for(int i = 1;i < b; i++) {
			if(a%i == 0) ans--;
		}
		printf("%lld\n", ans);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值