Pairs Forming LCM

题目链接:https://vjudge.net/problem/LightOJ-1236

解题思路:

如果LCM(a,b) = n

那么有如下结论:


对n进行质因子分解,pi表示n的质因子,ei表示pi的次数

n = p1^e1 * p2^e2...... * pn^en

那么对应a,b质因子分解,用ai,bi表示a,b对应质因子的次数

a = p1^a1 * p2^a2...... * pn^an

b = p1^b1 * p2^b2...... * pn^bn

对应e1 = max(a1,b1),e2 = max(a2,b2)......en = max(an,bn)


因此我们只需求出n所有质因子,以及质因子的次数。

那么ai,bi两个数只要一个取ei,另一个可以取0~ei,那么(ei+1)×2,其中ei,ei这组重复,所以总共 2×ei+1 对不同的

我们算出     \prod _{i=1}^{n}\left ( 2*ei+1 \right ),这样求出来是所有的对数,而我们需要的是b>=a的对数,算出的所有方法中只有有一种

情况是是a=b,就是每一对(ai,bi)都取ei,也就是每一对都相等,最后a,b才相同。因此总方法数有三种情况组成:

a>b + a<b + 特殊情况a=b


复杂度:O(sqrt(N))预处理2~sqrt(N)的素数,每次O(logN)质因子分解

O(sqrt(N)+ q*logN)

///本题结论:两个数的LCM的一种求法:各自质因子分解,取最每个质因子两边的较大系数就是LCM
///gcd就是都取较小值
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;

#define ll long long
#define for0(i,a,b) for (ll i=a;i<b;i++)
#define for1(i,a,b) for (ll i=a;i<=b;i++)

const int N = 1e7;

int prime[700000],tot;
bool vis[N+5];

void euler()
{
    tot = 0;
    for1(i,2,N){
        if (!vis[i]){
            prime[tot++] = i;
        }
        for (int j=0;j<tot&&i*prime[j]<=N;j++){
            vis[i*prime[j]] = true;
            if (i%prime[j]==0) break;
        }
    }
    //printf("tot=%d\n",tot);
}

bool leave;///是否可以被1e7的质数分解完
int cnt[700000];///1e7质数的大概数量

int main()
{
    euler();
    int T,ica=1;
    scanf("%d",&T);
    while (T--){
        leave = false;
        memset(cnt,0,sizeof cnt);
        ll n;
        scanf("%lld",&n);
        int now = 0;
        while (n!=1){
            if (now==tot) break;
            if (n%prime[now]==0) n/=prime[now],cnt[now]++;
            else now++;
        }
        if (n!=1) leave = true; ///没有用sqrt(N)内的质数分解完,剩余部分就是质数,且次数为1,总方法数*3
        ll ans = 1;
        for0(i,0,700000){
            if (cnt[i]) ans = ans*(2*cnt[i]+1);//,printf("cnt[%d]=%d\n",prime[i],cnt[i]);
        }
        if (leave) ans = ans*3; ///01,10,11
        printf("Case %d: %lld\n",ica++,(ans+1)/2);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值