Find the result of the following code:
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;
}
A straight forward implementation of the code may time out. If you analyze the code, you will find that the code actually counts the number of pairs (i, j) for which lcm(i, j) = n and (i ≤ j).
Input
Input starts with an integer T (≤ 200), denoting the number of test cases.
Each case starts with a line containing an integer n (1 ≤ n ≤ 1014).
Output
For each case, print the case number and the value returned by the function 'pairsFormLCM(n)'.
Sample Input
15
2
3
4
6
8
10
12
15
18
20
21
24
轉https://www.cnblogs.com/shentr/p/5285407.html
先來看個知識點: 素因子分解:n = p1 ^ e1 * p2 ^ e2 *..........*pn ^ en for i in range(1,n): ei 從0取到ei的所有組合 必能包含所有n的因子。 現在取n的兩個因子a,b a=p1 ^ a1 * p2 ^ a2 *..........*pn ^ an b=p1 ^ b1 * p2 ^ b2 *..........*pn ^ bn gcd(a,b)=p1 ^ min(a1,b1) * p2 ^ min(a2,b2) *..........*pn ^ min(an,bn) lcm(a,b)=p1 ^ max(a1,b1) * p2 ^ max(a2,b2) *..........*pn ^ max(an,bn) 哈哈,又多了種求gcd,lcm的方法。 題解: 先對n素因子分解,n = p1 ^ e1 * p2 ^ e2 *..........*pk ^ ek, lcm(a,b)=p1 ^ max(a1,b1) * p2 ^ max(a2,b2) *..........*pk ^ max(ak,bk) 所以,當lcm(a,b)==n時,max(a1,b1)==e1,max(a2,b2)==e2,…max(ak,bk)==ek 當ai == ei時,bi可取 [0, ei] 中的所有數 有 ei+1 種情況,bi==ei時同理。 那麼就有2(ei+1)種取法,但是當ai = bi = ei 時有重複,所以取法數爲2(ei+1)-1=2*ei+1。 除了 (n, n) 所有的情況都出現了兩次 那麼滿足a<=b的有 (2*ei + 1)) / 2 + 1 個 複製代碼 #include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long LL; const int N=1e7+5; const int NN=1e6; unsigned int prime[NN],cnt; //prime[N]會MLE bool vis[N]; void is_prime() { cnt=0; memset(vis,0,sizeof(vis)); for(int i=2;i<N;i++) { if(!vis[i]) { prime[cnt++]=i; for(int j=i+i;j<N;j+=i) { vis[j]=1; } } } } int main() { is_prime(); int t; cin>>t; for(int kase=1;kase<=t;kase++) { LL n; cin>>n; int ans=1; for(int i=0;i<cnt&&prime[i]*prime[i]<=n;i++) { if(n%prime[i]==0) { int e=0; while(n%prime[i]==0) { n/=prime[i]; e++; } ans*=(2*e+1); } } if(n>1) ans*=(2*1+1); printf("Case %d: %d\n",kase,(ans+1)/2); } } 複製代碼