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

LightOJ 1236 Pairs Forming LCM

題意:

long long pairsFormLCM( int n ) {
    long long res = 0;
    for( int i = 1; i <= n; i++ )
        for( int j = i; j <= n; j++ )
           if( lcm(i, j) == n ) res++; // lcm means least common multiple
    return res;
}

在n<=10^14的情況下實現上述代碼。

思路:

前些天還寫過一題算術基本定理的題解,現在發現理解還不夠透徹,比如這題按理來說應該是算術基本定理的模板題,但我居然沒看出來。。
求約數,倍數,質因數,gcd,lcm,都應該想到這個定理的。
算術基本定理的內涵用一句話來概括就是:

一個數的每一個質因子的不同冪對應不同的因數。

而這題,我們假設( a , b ) = n ,那麼:

n=pk11pk22pkss,a=pd11pd22pdss, b=pe11pe22pess,max(ei,di)=ki,kieidiki[0,ki]2(ki+1)ei=di=kii2(ki+1)1=2ki+1(a,b)(2k1+1)(2k2+1)(2ks+1)(a,b):[(2k1+1)(2k2+1)(2ks+1)+1]/2(n,n)+1

代碼:

/*
* @author FreeWifi_novicer
* language : C++/C
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>

using namespace std;

#define clr( x , y ) memset(x,y,sizeof(x))
#define cls( x ) memset(x,0,sizeof(x))
#define pr( x ) cout << #x << " = " << x << endl 
#define pri( x ) cout << #x << " = " << x << " " 
#define test( t ) int t ; cin >> t ; int kase = 1 ; while( t-- )
#define out( kase ) printf( "Case %d: " , kase++ )
#define mp make_pair
#define pii pair<int,int>
#define pb push_back
typedef long long lint;
typedef long long ll;
typedef long long LL;

const int maxn = 1e7 + 50 ;
bool noprime[maxn+50] ;
vector<int>p ;
int getPrime(){
    cls( noprime ) ;
    p.clear() ;
    int m = (int)sqrt( maxn + 0.5 ) ;
    for( int i = 2 ; i <= m ; i++ )
        if( !noprime[i] )
            for( int j = i * i ; j <= maxn ; j += i )
                noprime[j] = true ;
    for( int i = 2 ; i <= maxn ; i++ )
        if( !noprime[i] ) p.pb( i ) ;
    return p.size() ;
}

int pf[100][2] ;
int getPrifac( lint n , int len ){
    int pos = 0 ;
    for( int i = 0 ; p[i] * p[i] <= n && i < len ; i++ ){
        if( n % p[i] == 0 ){
            pf[++pos][0] = p[i] ;
            pf[pos][1] = 0 ;
            while( n % p[i] == 0 ){
                pf[pos][1] ++ ;
                n /= p[i] ;
            }
        }
    }
    if( n > 1 ){
        pf[++pos][0] = n ;
        pf[pos][1] = 1 ;
    }
    return pos + 1 ;
}
lint calc( lint n , int len ){
    int num = getPrifac( n , len ) ;
    lint res = 1 ;
    for( int i = 0 ; i < num ; i++ )
        res *= ( pf[i][1] * 2 + 1 ) ;
    res ++ ;
    res /= 2 ;
    return res ;
}
int main(){
    //freopen("input.txt","r",stdin);
    int len = getPrime() ;
    test( t ){
        lint n ; cin >> n ;
        out( kase ) ;
        cout << calc( n , len ) << endl ;
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章