数学知识 ---- 质数

质数

质数的定义

在大于 1 的整数中,只包含 1 和自己本身两个约数的数,被称为质数(素数)

质数的判定----试除法O(sqrt(n))

866. 试除法判定质数

给定 n 个正整数 ai,判定每个数是否是质数。

输入格式

第一行包含整数 n。

接下来 n 行,每行包含一个正整数 ai

输出格式

共 n 行,其中第 i 行输出第 i 个正整数 ai 是否为质数,是则输出 Yes,否则输出 No。

数据范围

1≤n≤100,
1≤ai≤231−1

输入样例:

2
2
6

输出样例:

Yes
No

数学知识 ---- 质数_第1张图片

#include
#include
#include
#include
#include
#include
#include
#include
#include

#define x first
#define y second

using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 100010;
const int MOD = 1000000007;
const int INF = 0x3f3f3f3f;

int gcd(int a, int b){return b ? gcd(b, a % b) : a;}
int lowbit(int x) {return x & -x;}

int n;

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

int main()
{
	cin >> n;
	for(int i = 0; i < n; i ++ ){
		int x;
		cin >> x;
		if(is_prime(x)) cout << "Yes" << endl;
		else cout << "No" << endl;
	}

	return 0;
}




分解质因数----试除法O(sqrt(n))

867. 分解质因数

给定 n 个正整数 ai,将每个数分解质因数,并按照质因数从小到大的顺序输出每个质因数的底数和指数。

输入格式

第一行包含整数 n。

接下来 n 行,每行包含一个正整数 ai。

输出格式

对于每个正整数 ai,按照从小到大的顺序输出其分解质因数后,每个质因数的底数和指数,每个底数和指数占一行。

每个正整数的质因数全部输出完毕后,输出一个空行。

数据范围

1≤n≤100,
2≤ai≤2×109

输入样例:

2
6
8

输出样例:

2 1
3 1

2 3

数学知识 ---- 质数_第2张图片

#include
#include
#include
#include
#include
#include
#include
#include
#include

#define x first
#define y second

using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 100010;
const int MOD = 1000000007;
const int INF = 0x3f3f3f3f;

int gcd(int a, int b){return b ? gcd(b, a % b) : a;}
int lowbit(int x) {return x & -x;}

int n;

void check(int x)
{
	
	for(int i = 2; i <= x / i; i ++ ){
		if(x % i == 0){
			int s = 0;
			while(x % i == 0){
				x /= i;
				s ++ ;
			}
			cout << i << " " << s << endl;
		}
	}
	if(x > 1) cout << x << " " << 1 << endl;
	cout << endl;
	
}

int main()
{
	cin >> n;
	for(int i = 0; i < n; i ++ ){
		int x;
		cin >> x;
		check(x);
	}

	return 0;
}




筛质数

868. 筛质数

给定一个正整数 n,请你求出 1∼n 中质数的个数。

输入格式

共一行,包含整数 n。

输出格式

共一行,包含一个整数,表示 1∼n 中质数的个数。

数据范围

1≤n≤106

输入样例:

8

输出样例:

4

基本思想

对于 2 3 4 5 6 7 8 9 10 11 12 … P
我们首先将 2 的倍数都筛掉
2 3 5 7 9 11 … P
然后再将 3 的倍数都筛掉
2 3 5 7 11 … P


最后,对于 P 来说,将 P 的倍数都筛掉,对于 P 之前的数来说,都已经被前面的数筛过了,也就是说, P 一定是质数

朴素法O(nlogn)

#include
#include
#include
#include
#include
#include
#include
#include
#include

#define x first
#define y second

using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1000010;
const int MOD = 1000000007;
const int INF = 0x3f3f3f3f;

int gcd(int a, int b){return b ? gcd(b, a % b) : a;}
int lowbit(int x) {return x & -x;}

int n;
bool st[N];
int prime[N], cnt;

void check(int x)
{
	
	for(int i = 2; i <= n; i ++ ){
		if(!st[i]){
			prime[cnt ++ ] = i;
		}
		for(int j = i; j <= n; j += i){
			st[j] = true;
		}
	}
	
}

int main()
{
	cin >> n;
	check(n);
	
	cout << cnt << endl;

	return 0;
}




埃式筛法O(nloglogn)

由朴素法优化而来,对于 P 来说,前面的合数,会在前面筛的时候,被一些质数筛掉,因此,我们就只需要将质数的倍数筛掉即可

#include
#include
#include
#include
#include
#include
#include
#include
#include

#define x first
#define y second

using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1000010;
const int MOD = 1000000007;
const int INF = 0x3f3f3f3f;

int gcd(int a, int b){return b ? gcd(b, a % b) : a;}
int lowbit(int x) {return x & -x;}

int n;
bool st[N];
int prime[N], cnt;

void check(int x)
{
	
	for(int i = 2; i <= n; i ++ ){
		if(!st[i]){
			prime[cnt ++ ] = i;
			for(int j = i; j <= n; j += i){
				st[j] = true;
			}
		}
	}
	
}

int main()
{
	cin >> n;
	check(n);
	
	cout << cnt << endl;

	return 0;
}




线性筛法O(n)

void get_primes(){
    //外层从2~n迭代,因为这毕竟算的是1~n中质数的个数,而不是某个数是不是质数的判定
    for(int i=2;i<=n;i++){
        if(!st[i]) primes[cnt++]=i;
        for(int j=0;primes[j]<=n/i;j++){//primes[j]<=n/i:变形一下得到——primes[j]*i<=n,把大于n的合数都筛了就
        //没啥意义了
            st[primes[j]*i]=true;//用最小质因子去筛合数

            //1)当i%primes[j]!=0时,说明此时遍历到的primes[j]不是i的质因子,那么只可能是此时的primes[j]
            //最小质因子,所以primes[j]*i的最小质因子就是primes[j];
            //2)当有i%primes[j]==0时,说明i的最小质因子是primes[j],因此primes[j]*i的最小质因子也就应该是
            //prime[j],之后接着用st[primes[j+1]*i]=true去筛合数时,就不是用最小质因子去更新了,因为i有最小
            //质因子primes[j]
            //退出循环,避免之后重复进行筛选。
            if(i%primes[j]==0) break;
        }
    }

}

#include
#include
#include
#include
#include
#include
#include
#include
#include

#define x first
#define y second

using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1000010;
const int MOD = 1000000007;
const int INF = 0x3f3f3f3f;

int gcd(int a, int b){return b ? gcd(b, a % b) : a;}
int lowbit(int x) {return x & -x;}

int n;
bool st[N];
int prime[N], cnt;

void check(int x)
{
	
	for(int i = 2; i <= n; i ++ ){
		if(!st[i]){
			prime[cnt ++ ] = i;
		}
		for(int j = 0; prime[j] <= n / i; j ++ ){
			st[prime[j] * i] = true;
			if(j % prime[j] == 0) break;
		}
	}
	
}

int main()
{
	cin >> n;
	check(n);
	
	cout << cnt << endl;

	return 0;
}




你可能感兴趣的:(AcWing-算法基础,c++,算法,图论)