唯一分解定理一篇就够了

如果与唯一定理一起应用需要用到素数筛,可以看这篇文章:
线性筛判断素数


唯一分解定理:

任何一个大于1的自然数 N,如果N不为质数,**那么N可以唯一分解成有限个质数的乘积:
在这里插入图片描述
这里P1

定理应用:

唯一分解定理一篇就够了_第1张图片
3.用唯一分解求a,b的gcd,lcm(ak,bk为质数的幂):

唯一分解定理一篇就够了_第2张图片

4.在不取mod的情况下,用唯一分解求组合数:
在这里插入图片描述

解释:

  1. 因子:如果a%b==0,就称b是a的因子,例如8的因子有: 1,2,4,8;
  2. 因数:假如a*b=c(a、b、c都是整数),那么我们称a和b就是c的因数。

用代码实现:

1.素数分解–欧拉筛(线性筛)

#define maxn 10000001
bool number[maxn+5];
ll prime[maxn/10];//素数不能开到1e7
int len;
void isprime()
{
     
    len=0;
    memset(number,true,sizeof(number));
    for(int i=2; i<=maxn; i++)
    {
     
        if(number[i])
            prime[len++]=i;
        for(int j=0; j<len&&prime[j]*i<=maxn; j++)
        {
     
            number[prime[j]*i]=false;
            if(i%prime[j]==0)
                break;
        }
    }
}

2.唯一分解定理:

int factor[10000];
void geta(ll n)//算ai等于多少(幂指数)
{
     
	memset(factor,0,sizeof(factor));
    int cas=0;
    for(int i=0;i<len&&prime[i]*prime[i]<=n;i++)
    {
     
        while(n%prime[i]==0)//这里不能改
        {
     
            factor[cas]++;
            n/=prime[i];
        }
        if(factor[cas])
            cas++;
    }
    if(n>1)//prime[i]*prime[i]<=nn当不满足这个条件的时候就应该还有一个素数的一次方
        factor[cas]=1;
}
int p[100001];
void getp(ll q)//筛出唯一分解定理的底数
{
     
	cnt = 0;
    for (int i = 2, x = q; (long long)i * i <= q; i++)//筛出q的p1,p2,p3...(唯一分解定理里面的底数)
        if (!(x % i))
        {
     
            p[++cnt] = i;
            while (!(x % i))
                x /= i;
        }
    //例如q=300000时,q=2^5*3^1*5^5,此时数组a中存储的元素是2,3,5,cnt=3;
    if (x > 1)  //如果最后x大于1,即最后产生了一个小的素数,直接保存即可
        p[++cnt] = x, x = 1;
}

前两天碰到的一道codeforces上的题:
C. Division–素数筛+唯一分解定理
Pairs Forming LCM LightOJ - 1236

侵删

你可能感兴趣的:(唯一分解定理一篇就够了)