寒假训练营 基础数论 第3节 笔记

筛质数

朴素筛法 O(n√n)

素数的因子仅有 1 和它本身。它一旦存在其他因子,就不是素数了,那么我们就可以将其的全部倍数筛除,剩下的就都是素数了。
代码

//朴素筛法 
#include<iostream>

using namespace std;

bool st[10010];
int primes[10010];
int cnt = 0;

void get_primes(int n)
{
	st[1] = true;
	for(int i = 2 ; i <= n ; i++)
	{
		if(!st[i]) primes[++cnt] = i;	 //为 false 的是质数,存进primes数组里。 
		for(int j = i+i ; j <= n ; j += i)	//将每个数的倍数标记为 true; 
		{
			st[j] = true;
		}
	}
	
}

int main()
{
	int n;
	cin >> n;
	get_primes(n);
	for(int i = 1 ; i <= cnt ; i++)
		cout << primes[i] << " "; 
	
	return 0;
 }

埃氏筛 O(n logn)

埃氏筛法解决了部分重复标记的问题(素数的倍数标记,合数不标记),是朴素筛的优化
代码

//埃氏筛	O(n logn); 
#include<iostream>

using namespace std;

bool st[10010];
int primes[10010];
int cnt = 0;

void get_primes(int n)
{
	st[1] = true;
	for(int i = 2 ; i <= n ; i++)
	{
		if(!st[i])//符合判断条件的全是质数 
		{
			primes[++cnt] = i;	 //为 false 的是质数,存进primes数组里。 
			for(int j = i+i ; j <= n ; j += i)	//将质数的倍数标记为 true; 
			{
				st[j] = true;
			}
		}
	}
	
}

int main()
{
	int n;
	cin >> n;
	get_primes(n);
	for(int i = 1 ; i <= cnt ; i++)
		cout << primes[i] << " "; 
	
	return 0;
 } 

线性筛法(欧拉筛) O(n)

线性筛完美解决了埃氏筛法的重复问题。是朴素筛和埃氏筛的优化版本。
代码

//线性筛(欧拉筛)
#include<iostream>

using namespace std;

bool st[10010];
int primes[10010];
int cnt = 0;

void get_primes(int n)
{
	st[1] = true;
	for(int i = 2 ; i <= n ; i++)
	{
		if(!st[i]) primes[++cnt] = i; 
		for(int j = 1 ; j <= cnt && 1 * primes[j] <= n ; j ++) 
		{
			st[i * primes[j]] = true;
			if(i % primes[j] == 0) break;
		}
	}
	
}

int main()
{
	int n;
	cin >> n;
	get_primes(n);
	for(int i = 1 ; i <= cnt ; i++)
		cout << primes[i] << " "; 
	
	return 0;
 } 

快速幂

计算指数时,用于快速计算。

//快速幂  求 a^n 的值 
#include<iostream>

using namespace std;

const long long = ll ;

ll fastpow(ll a , ll n)
{
	if(n == 1) return a;
	ll temp = fastpow(a , n/2);
	if(n % 2 == 1) return temp * temp * a;
 } 

/*
(a + b) % p = (a % p + b % p) % p (1)

(a - b) % p = (a % p - b % p ) % p (2)

(a * b) % p = (a % p * b % p) % p (3)
*/

int main()
{
	cin >> a >> n;
	ll ans = fastpow(a , n);
	
	cout << ans;
	
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值