Pairs Forming LCM LightOJ - 1236 (算术基本定理)

题意:

就是求1-n中有多少对i 和 j 的最小公倍数为n  (i <= j)

解析:

而这题,我们假设( a , b ) = n ,那么: 

n=pk11pk22⋯pkss,

a=pd11pd22⋯pdss, b=pe11pe22⋯pess,

以确定max(ei,di)=ki,      关于这点 可以自己反证一下

那么ki的组成就是eidi中一个等于ki

另一个任取[0,ki-1]中的一个数,

那么就有 2ki 种方案,

由于 ei=di=ki 只有一种,(两种都为ki)

所以第i位方案数为2ki+1

有序对(a,b)方案数就是(2k1+1)(2k2+1)⋯(2ks+1)

无序对(a,b)方案数就是:{[(2k1+1)(2k2+1)⋯(2ks+1)] + 1}/2

(n,n)已经只有一个,不会重复,所以+1 再除 2

 

 

代码:

#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define maxn 10000900
#define Pair pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define _  ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int LL_INF = 0x7fffffffffffffff,INF = 0x3f3f3f3f;
LL primes[maxn/10];
bool vis[maxn];
LL ans = 0;
void init()
{
    mem(vis,0);
    for(int i=2; i<maxn; i++)
        if(!vis[i])
        {
            primes[ans++] = i;
            for(LL j=(LL)i*i; j<maxn; j+=i)
                vis[j] = 1;
        }
}

int main()
{
    init();
    int T;
    int kase = 0;
    cin>> T;
    while(T--)
    {
        LL n, res = 1, cnt = 0;
        cin>> n;
        for(LL i=0; i<ans && primes[i] * primes[i] <= n; i++)
        {
            LL cnt2 = 0;
            while(n % primes[i] == 0)
            {
                n /= primes[i];
                cnt2++;
            }
            if(cnt2 > 0)
            {
                res *= (2*cnt2 + 1);
            }
        }
        if(n > 1)
        {
            res *= 3;
        }
        printf("Case %d: %lld\n",++kase,res/2+1);
    }
    return 0;
}

 

posted @ 2018-06-14 21:55  WTSRUVF  阅读(360)  评论(0编辑  收藏  举报