质数判定 及筛选 及分解质因数 (模板) 及例题

质数判定

试除法:
若正整数N是合数,则存在一个能整除N的数T,且T <= sqrt(N)。

代码:
判断一个数是不是质数。

#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#include<iostream>
#define int long long
using namespace std;

const int N = 1e3+10;

bool is_prime(int x){
	if(x < 2) return false;
	for(int i=2;i<=x/i;i++){
		if(x % i == 0) return false;
	}
	return true;
}

signed main(){
	int n; cin>>n;
	cout<<is_prime(n)<<endl;
	return 0;
}

筛法:

埃氏筛法:
从2开始,把每一个的倍数标记一下,被标记的一定不是质数,对于每一个数,从它的平方开始标记能完全筛出所有质数。

#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#include<iostream>
#include<cstring>
#define int long long
using namespace std;

const int N = 1e3+10;

bool vis[N];
int primes[N],cnt;

void get_primes(int n){
	memset(vis,false,sizeof(vis));
	for(int i=2;i<=n;i++)
		if(!vis[i]){
			primes[cnt++] = i;
			for(int j=i*i;j<=n;j+=i) vis[j] = true;
		}
}

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

欧拉筛:

让每一个质因数被它的最小质因子标记。

#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#include<iostream>
#include<cstring>
#define int long long
using namespace std;

const int N = 1e3+10;

bool vis[N];
int primes[N],cnt;

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

signed main(){
	
	int n; cin>>n;
	ols(n);
	for(int i=0;i<cnt;i++) cout<<primes[i]<<endl;
	
	return 0;
}

质因数分解:

唯一分解定理:任何一个大于1的数都能唯一分解为有限个质数的乘积

N = p 1 c 1 ∗ p 2 c 2 ∗ . . . ∗ p m c m N = p_{1}^{c_1}*p_{2}^{c_2}*...*p_{m}^{c_m} N=p1c1p2c2...pmcm

结合试除法和埃氏筛的思想,枚举2~sqrt(n)的所有数d,去除掉当前值的所有因子d,并统计个数

#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#include<iostream>
#include<cstring>
#define int long long
using namespace std;

const int N = 1e3+10;

int p[N],c[N],cnt;

signed main(){
	int n; cin>>n;
	for(int i=2;i<=n/i;i++){
		if(n % i == 0){
			p[++ cnt] = i;
			while(n % i == 0) c[cnt] ++,n /= i;
		}
	}
	
	if(n > 1) p[++ cnt] = n,c[cnt] = 1;
	
	for(int i=1;i<=cnt;i++) cout<<p[i]<<" "<<c[i]<<endl;
	
	return 0;
}

例题:

洛P1865

埃氏筛

#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#include<iostream>
#include<cstring>
#define int long long
using namespace std;

const int N = 1e6+10;

bool vis[N];
//int primes[N],cnt;
int sum[N];

void get_primes(int n){
	for(int i=2;i<=n;i++)
		if(!vis[i]){
//			primes[cnt++] = i;
			for(int j=i*i;j<=n;j+=i) vis[j] = true;
		}
}

signed main(){
	
	int n,m; cin>>n>>m;
	get_primes(m);
	for(int i=2;i<=m;i++) {
		sum[i] = sum[i-1];
		if(!vis[i]) sum[i] ++;
	}
	
	while(n --){
		int l,r; cin>>l>>r;
		if(l >= 1 && l <= m && r >= 1 && r <= m && l <= r)
			cout<<(sum[r] - sum[l-1])<<endl;
		else cout<<"Crossing the line"<<endl;
	}
	
	return 0;
}

欧拉筛

#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#include<iostream>
#include<cstring>
#define int long long
using namespace std;

const int N = 1e6+10;

int sum[N];
bool vis[N];
int primes[N],cnt;

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

signed main(){
	
	int n,m; cin>>n>>m;
	ols(m);
	for(int i=2;i<=m;i++) {
		sum[i] = sum[i-1];
		if(!vis[i]) sum[i] ++;
	}
	
	while(n --){
		int l,r; cin>>l>>r;
		if(l >= 1 && l <= m && r >= 1 && r <= m && l <= r)
			cout<<(sum[r] - sum[l-1])<<endl;
		else cout<<"Crossing the line"<<endl;
	}
	
	return 0;
}

P3912 (内存,性质N内大约有N/log(N)个质数)
Codeforces Round #686 (Div. 3) D 唯一分解定理。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值