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

来源:互联网 发布:食品行业进销存软件 编辑:程序博客网 时间:2024/04/29 08:11
对于初识数论的我来说这是很好的一道题,因为通过它我扩展了不少东西:算术基本定理,线性筛素数,欧拉函数,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 1000010ll 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;}


0 0
原创粉丝点击