1. 程式人生 > >算數基本原理(唯一分解定理)

算數基本原理(唯一分解定理)

唯一分解定理:
任意一個大於0的正整數都能被表示成若干個素數的乘積且表示方法是唯一的;整理可以將相同素數的合併
X=p1^a1*p2^a2……pn^an;
p1..pn 為素數
數X的因子數為num=(1+a1)*(1+a2)……(1+an);

/*思路:首先篩選出所有的素數,然後用一個數組儲存所有的素數,然後通過數學,用上
唯一分解定理,算出s的所有因子,計算個數,因為算出來的個數num,(由於(a,b)(b,a)算一個並且沒有正方形,所以num/2,然後計算在a以下的因子,num——*/ 

#include<iostream>
#include<cstdio>
#include<cstring> #include<cmath> using namespace std; typedef long long ll; const ll maxn=1e6+10; ll primes[maxn]={1,1,0}; ll p[maxn]; void sushu(ll n) { int k=0; for(int i=2;i<maxn;i++) if(!primes[i]) { p[k++]=i;//存素數 for(int j=i;j<maxn;j+=i) primes[j]=1
; } } ll solve(ll n) { //sushu(maxn); ll num=1; for(int i=0;p[i]<=sqrt(n);i++) { int ans=0; if(n%p[i]==0) while(n%p[i]==0) { ans++; n/=p[i]; } num=num*(ans+1); } if(n>1) num*=2; return
num; }//求n的因子數 int main() { sushu(maxn); int t,n; ll s,a; scanf("%d",&t); for(int m=1;m<=t;m++) { ll ans=0; scanf("%lld%lld",&s,&a); ans=solve(s); if(a*a>=s) printf("Case %d: 0\n",m); else{ ans=ans/2; for(int i=1;i<a;i++) if(s%i==0) ans--; printf("Case %d: %d\n",m,ans); /*if(m!=t) printf("\n");*/ } } return 0; }