Light oj Trailing Zeroes (I) (算術基本定理)

對於初識數論的我來說這是很好的一道題,因爲通過它我擴展了不少東西:算術基本定理,線性篩素數,歐拉函數,Miller Rabin質數分解和Pollard Rho大整數分解(見模板,較爲少用)
  主要是對算術基本定理(質因數分解定理)的應用(百度之),求一個數因數的個數。
  首先用線性篩素數法篩出所有的小於等於 sqrt(n) 的素數,然後枚舉素數即可,有一點需要注意:
  一個數 n 的質因數最多有一個大於 sqrt(n),我簡單證明了一下:
            設若有兩個或多個,取a和b,則a和b的最小公倍數爲 a*b>n,而a,b又整除n,所以矛盾,故證明之。

  所以在枚舉完所有的素數之後,若 n>1 則說明還有一個大於sqrt(n)的素因子,它的指數爲1,所以要乘2

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<math.h>
#include<stdlib.h>
using namespace std;
#define ll long long
#define maxn 1000010
ll prime[maxn],n,ans;
int flag[maxn],num;
void get_prime(){
    memset(flag,0,sizeof(flag));
    num=0;
    for(ll i=2;i<maxn;i++){
        if(!flag[i]) prime[++num]=i;
        for(ll j=1;j<=num&&i*prime[j]<maxn;j++){
            flag[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
}
int main(){
    int i,j,t;
    cin>>t;
    get_prime();
    for(i=1;i<=t;i++){
        scanf("%lld",&n);
        ans=1;
        for(j=1;j<=num&&prime[j]<=sqrt(n+0.5);j++){
            if(n<prime[j]) break;
            if(n%prime[j]==0){
                int a=1;
                while(n%prime[j]==0){
                    n/=prime[j];
                    a++;
                }
                ans*=a;
            }
        }
        if(n>1) ans*=2;
        ans--;   //把1去掉
        printf("Case %d: %lld\n",i,ans);
    }
    return 0;
}


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