LightOJ 1236 Pairs Forming LCM(唯一分解定理+素数筛)

26 篇文章 0 订阅
5 篇文章 0 订阅

Pairs Forming LCM

题解:考虑唯一分解定理: a = p 1 n 1 ⋅ p 2 n 2 . . . p k n k a = {p_1}^{n_1}\cdot {p_2}^{n_2}...{p_k}^{n_k} a=p1n1p2n2...pknk b = p 1 m 1 ⋅ p 2 m 2 . . . p k m k b = {p_1}^{m_1}\cdot {p_2}^{m_2}...{p_k}^{m_k} b=p1m1p2m2...pkmk
{ l c m ( a , b ) = p 1 m a x ( n 1 , m 1 ) ⋅ p 2 m a x ( n 2 , m 2 ) . . . p k m a x ( n k , m k ) g c d ( a , b ) = p 1 m i n ( n 1 , m 1 ) ⋅ p 2 m i n ( n 2 , m 2 ) . . . p k m i n ( n k , m k ) \begin{cases}lcm(a,b) = {p_1}^{max(n_1,m_1)}\cdot {p_2}^{max(n_2,m_2)}...{p_k}^{max(n_k,m_k)}\\\\gcd(a,b) = {p_1}^{min(n_1,m_1)}\cdot {p_2}^{min(n_2,m_2)}...{p_k}^{min(n_k,m_k)}\end{cases} lcm(a,b)=p1max(n1,m1)p2max(n2,m2)...pkmax(nk,mk)gcd(a,b)=p1min(n1,m1)p2min(n2,m2)...pkmin(nk,mk)
所以我们考虑将 n n n质因子分解 n = p 1 e 1 ⋅ p 2 e 2 . . . p k e k n = {p_1}^{e_1}\cdot {p_2}^{e_2}...{p_k}^{e_k} n=p1e1p2e2...pkek,有 e i = m a x ( n i , m i ) e_i = max(n_i,m_i) ei=max(ni,mi)

对于 i = p 1 n 1 ⋅ p 2 n 2 . . . p k n k i = {p_1}^{n_1}\cdot {p_2}^{n_2}...{p_k}^{n_k} i=p1n1p2n2...pknk时和 j = p 1 m 1 ⋅ p 2 m 2 . . . p k m k j = {p_1}^{m_1}\cdot {p_2}^{m_2}...{p_k}^{m_k} j=p1m1p2m2...pkmk时的每一个质因子的指数我们都有 m a x ( n i , m i ) + 1 max(n_i,m_i) + 1 max(ni,mi)+1种取法,再除去 i = x ⋅ p m i = x\cdot p^m i=xpm j = x ⋅ p n j= x\cdot p^n j=xpn的情况,因此总共就是 2 ( e i + 1 ) − 1 2(e_i+1) - 1 2(ei+1)1种,然后又根据乘法原理有 ∏ ( 2 ⋅ e i + 1 ) \prod{(2\cdot e_i+1)} (2ei+1),最后除去 i > j i>j i>j和加上指数相等的情况,就有 a n s = ∏ 2 ⋅ e i + 1 2 + 1 ans = \frac{\prod{2\cdot e_i + 1}}{2} + 1 ans=22ei+1+1

代码

#include<bits/stdc++.h>
typedef long long LL;
using namespace std;
const int N = 1E7+10, M = N / log(N) + N/10;
int prime[M], k;
bool vis[N];
void init()
{
	for(int i = 2; i < N; ++i) {
		if(vis[i] == 0)
			prime[k++] = i;
		for(int j = 2; j * i < N; ++j) {
			if(vis[i * j] == 0) 
				vis[i * j] = 1;
		}
	}
}

LL solve(LL n)
{
	LL t = n, ans = 1;
	for(int i = 0; i < k && prime[i] <= sqrt(t); ++i) {
		int cnt = 0;
		while(n % prime[i] == 0) {
			cnt++;
			n /= prime[i];
		}
		ans *= (2 * cnt + 1);
	}
	if(n > 1) ans *= (2 * 1 + 1);
	return ans / 2 + 1;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.in","r",stdin);
#endif
	init();
	int T, t = 1;
	cin >> T;
	while(T--) {
		LL n;
		cin >> n;
		LL ans = solve(n);
		cout << "Case "<< t++ << ": " << ans << endl;
	}
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值