H - Pairs Forming LCM
阿新 • • 發佈:2018-11-15
題目連結:https://cn.vjudge.net/contest/70017#problem/H
題目大意:給你一個數n,讓你在n中找一對a,b兩個值且a<b,使得a和b的最大公倍數是n。
題解:唯一分解定理,把每一個a和b分解成以素數為因子的乘積(算數基本定理那樣),需要取每一個素數因子的指數最大的那素因子然後相乘,使得到的數為n。
例如a=a1^e1*a2^e2.........ax^ex b= b1^z1*b2^z2...........bx^zx; n=n1^y1*n2^y2...........nx^yx;
對於每一個素因子當ei=yi,zi可以選取0到yi的值所以有yi+1中情況,對於zi=yi,e1可以選取0到yi-1所以有yi中情況,所以對於每一個元素來說sum*=(2*yi+1);因為除了a=n,b=n的情況其他符合條件的情況都有2種,因為要選取a<=b的那種,所以最後(sum/2)+1;
程式碼:
#include <iostream> #include <algorithm> #include <stdio.h> #include <stdlib.h> #include <string.h> #define inf 0x3f3f3f3f using namespace std; const int MAX=1e7+5; int prime[MAX/10]; bool vis[MAX+1]; int k; void getprime() { k=0; memset(vis,0,sizeof(vis)); for(int i=2;i<=MAX;i++) { if(!vis[i]) prime[++k]=i; for(int j=1;j<=k&&prime[j]*i<MAX;j++) { vis[prime[j]*i]=1; if(i%prime[j]==0) break; } } } int main() { int T,m=0; long long int a,b; scanf("%d",&T); getprime(); while(T--){ ++m; scanf("%lld",&a); long long int ans=1; for(b=1;b<=k&&a>=prime[b]*prime[b];b++) { if(a%prime[b]==0) { int cnt=0; while(a%prime[b]==0) { a=a/prime[b]; cnt++; } ans*=(cnt*2+1); } } if(a>1) ans=ans*3; printf("Case %d: %lld\n",m,ans/2+1); } return 0; }