1. 程式人生 > >LightOJ 1236 Pairs Forming LCM(算術基本定理)

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)e
i
=di=ki
i2(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] ;