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

来源:互联网 发布:sql having count(*) 编辑:程序博客网 时间:2024/06/04 18:59

Aladdin and the Flying Carpet

唯一分解定理:
任意一个大于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;}