如果与唯一定理一起应用需要用到素数筛,可以看这篇文章:
线性筛判断素数
唯一分解定理:
任何一个大于1的自然数 N,如果N不为质数,**那么N可以唯一分解成有限个质数的乘积:
这里P1<P2<P3…<Pn均为质数,其中指数ai是正整数。这样的分解称为 N 的标准分解式。
定理应用:
3.用唯一分解求a,b的gcd,lcm(ak,bk为质数的幂):
4.在不取mod的情况下,用唯一分解求组合数:
解释:
- 因子:如果a%b==0,就称b是a的因子,例如8的因子有: 1,2,4,8;
- 因数:假如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
侵删