素数与埃氏筛选法
筛法解决的问题主要是筛选出一类具体特殊性质的数。范围通常是 [1,𝑛]。
最经典的问题就是筛选素数。
素数:即其因数只有 1 和其本身的数。特殊的,1 不是素数。
埃拉托斯特尼筛法,是一类十分简单,并且好理解的筛法。
采用一种从小到大的过程,对于整数 x,我们将区间内的所有的 𝑥 的倍数都标记为合数(非素数)即可。
具体的流程,我们从 22 开始循环,如果当前数 𝑥x没有被标记。那么当前数一定是素数,否则是合数,然后我们依次枚举 x 的倍数 2𝑥,3𝑥,4𝑥...,并且将其标记。然后继续循环即可。
模板代码
vector<ll>v1; //存放素数
bool vis_v1[N]; //标记素数
void era(ll n)
{
for(ll i=1;i<=n;i++)
{
vis_v1[i]=true; //初始化标记
}
for(ll i=2;i<=n;i++)
{
if(vis_v1[i])
v1.push_back(i); //没被标记代表是素数 加入数组
for(ll j=i+i;j<=n;j+=i)
{
vis_v1[j]=false; //做标记
}
}
}
真题演练
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1e7;
ll n;
vector<ll>v1; //存放素数
bool vis_v1[N]; //标记素数
void era(ll n)
{
for(ll i=1;i<=n;i++)
{
vis_v1[i]=true; //初始化标记
}
for(ll i=2;i<=n;i++)
{
if(vis_v1[i])
v1.push_back(i); //没被标记代表是素数 加入数组
for(ll j=i+i;j<=n;j+=i)
{
vis_v1[j]=false; //做标记
}
}
}
int main()
{
cin>>n;
era(n);
cout<<v1[1e5+1]<<endl;
return 0;
}
整数分解
最大公约数-gcd
真题演练
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
ll gcd(ll a,ll b)
{
ll t=max(a,b);
ll k=min(a,b);
a=t;
b=k;
while(b!=0)
{
int r=a%b;
a=b;
b=r;
}
return a; //a即为所求最大公约数
}
int main()
{
ll a,b;
cin>>t;
while(t--)
{
cin>>a>>b;
cout<<gcd(a,b)<<endl;
}
return 0;
}