//质数的快速线性筛法,不会重复筛选
//1.对于(质数*质数)的情况:不会出现重复筛的情况
//2.对于(质数*合数)的情况:就会出现重复筛,例如4*3,6*2
//由于任意个合数可以分解为质数的乘积,p=p1*p2...*pn(p1为最小的质数)
//当一个合数乘上一个比他最小的质数还要小或等于的质数时不会重复筛,所以当p%p1=0时,停止筛选
int Prime[N],isNotPrime[N],num_prime = 0;
void getPrime( int n )
{
fill( isNotPrime , isNotPrime+N , 0 );
for( int i = 2 ; i < n ; ++i ){
if( !isNotPrime[i] ) Prime[num_prime++] = i;
for( int j = 0 ; j < num_prime && i*Prime[j] < n ; ++j ){
isNotPrime[i*Prime[j]] = 1;
if( i%Prime[j] == 0 ) break;
}
}
}
//欧拉函数线性打表
//欧拉函数是小于n且与n互质的数的个数,f(1)=1,例如f(8)=4,有1,3,5,7
//设n=p1*p2...*pn(pi是n的质数),则f(n)=n*(1-1/p1)*(1-1/p2)...*(1-1/pn)
int oula[N];
void getLa( int n )
{
for( int i = 0 ; i < n ; ++i ) oula[i] = i;
for( int i = 2 ; i < n ; ++i ){
//i为质数
if( oula[i] == i ){
for( int j = 1 ; j*i < n ; ++j ){
oula[j*i] -= oula[j*i]/i;
}
}
}
}
//求某数正因子个数打表
//算数基本定理求正因子个数
//设n=p1^a1*p2^a2...*pn^an(pi是n的质数,ai是质数的次幂)
//f(n)=(a1+1)*(a2+1)...*(a3+1)
int num[N];
void getNumDivisor( int n )
{
fill( num , num+N , 0 );
for( int i = 1 ; i*i < n ; ++i ){
for( int j = i ; i*j < n ; ++j ){
num[i*j] += 2;
if( i == j ) num[i*j]--;
}
}
}
//求某数所有正因子和打表
//算数基本定理求所有正因子个数和
//设n=p1^a1*p2^a2...*pn^an(pi是n的质数,ai是质数的次幂)
//f(n)=(1+p1...p1^a1)*(1+p2...+p2^a2)...*(1+pn...+pn^an)
//等比数列乘积
int sum[N];
void getSumdivisor( int n )
{
fill( sum , sum+N , 0 );
for( int i = 1 ; i*i < n ; ++i ){
for( int j = i ; i*j < n ; ++j ){
sum[i*j] += i+j;
if( i == j ) sum[i*j] -= i;
}
}
}
质数快速筛法;欧拉函数线性打表;因子个数,因子和打表
最新推荐文章于 2024-02-14 15:23:06 发布