基于数论的常用算法gcd 、ex_gcd,素数

1、gcd():最大公约数

int gcd(a,b){//算法导论上指出a、b为非负整数,不用在意两者的大小关系
if b==0 return a;
else return gcd( b,a % b)
}//时间复杂度O(log max(a,b))

gcd &&lcm:

long long gcd(long long a, long long b)
{ return a == 0 ? b : gcd(b % a, a); }
long long  lcm(long long  a, long long b)
{ return a * b / gcd(a, b); }

2、ex_gcd():扩展欧几里得算法

一定存在整数对(x,y)使得ax+by=gcd(a,b)。此处省略一万字数学证明

int extgcd(int a,int b,int x, int y){
	int d =a;
	if(b!=0){
		d = extgcd(b,a%b,y,x);
		y -= (a/b)*x;
	}
	else{
		x=1;
		y=0;
	}
	return d;//返回的是gcd(a,b) ,时间内复杂度同上
} 

3、素数:

1、对于单独判断一个数字是否为素数,只要从2~根号n之间找即可。

2、输出或统计n以内有多少素数时,采用线性筛,复杂度O(n)

int p[NMAX], pn;
bool not_prime[NMAX];

void prime()
{
    pn = 0;
	not_prime[1] = 1;
    for(int i = 2; i < NMAX; i++)
    {
        if(!not_prime[i]) p[pn++] = i;
		for(int j = 0; j < pn && i * p[j] < NMAX; j++)
        {
            not_prime[i * p[j]] = 1;
            if(i % p[j] == 0) break;
        }
    }
}

 

3、求一个区间内的素数个数:

解释一下:因为b内的合数最小质因数一定不消耗国根号b。即先分别做好[2,根号b)的表和[a,b)的表,然后从小的表里筛得素数的同时,将他的倍数从大表中划去即可。

bool is_prime[1000010]; 
bool is_prime_small[1000010];  
  
void segment_sieve(ll a, ll b)  
{  
    for(int i=0; (ll)i*i<b; i++) is_prime_small[i] = true;//i是素数  
    for(int i=0; i<b-a; i++) is_prime[i] = true;  
    //利用0~len代表a~b的数  
    for(int i=2; (ll)i*i<b; i++)  
    {  
        if(is_prime_small[i])  
        {  
            for(int j=i+i; (ll)j*j<b; j+=i)  
                is_prime_small[j] = false; //筛[2,√b)  
            for(ll j=max(2LL, (a+i-1)/i)*i; j<b; j+=i)  
                is_prime[j-a] = false; //筛[a,b)  
            //j代表素数,j-a是将a~b变为0~b-a以便数组好存储  
            //2LL是2的长整形形式,与其比较意思是j最少是i的两倍  
            //((a+i-1)/i)*i得出的是(>=a && %i==0)离a最近的数,其实  
            //也可以写成a%i==0 ? a : (a/i+1)*i  
        }  
    }  
}  

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值