zzx:做一下【模板】欧拉定理吧
yxy:啥玩意啊OAO
zzx:噢对了,你会不会算Phi
yxy:那是啥啊qwq
zzx:……你会不会写欧筛
yxy:不会!(逃)
zzx:qwq你先去做一下埃筛模板吧
给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内)
1.暴力无脑筛素数qwq
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define MAXN 10000005
#define MAXM
#define scanf(a) scanf("%d",&a)
#define print(a) printf("%d",&a)
#define printn(a) printf("%d
",a)
using namespace std;
int n,m,ans;
bool prime[MAXN];
void init()
{
scanf(n); scanf(m);
memset(prime,true,n+1);
prime[0]=false; prime[1]=false;
}
void f_prime()
{
for (int i=3;i<=n;i++)
{
for (int j=2;j<=sqrt(i);j++)
{
if (!(i%j))
{
prime[i]=false;
break;
}
}
}
}
void start()
{
f_prime();
for (int i=1,a;i<=m;i++)
{
scanf(a);
if (prime[a])
{
printf("Yes
");
continue;
}
printf("No
");
}
}
int main()
{
init();
start();
return 0;
}
保你T飞www
2.埃拉托斯特尼筛法(其实这才叫(普通筛法))
主要思想-->素数的倍数一定不是一个素数
初始化,将每个数都标记为是素数
然后找到一个当前被标记为素数的(i)的就将(i)的倍数都标记为非素数。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define MAXN 10000005
#define MAXM
#define scanf(a) scanf("%d",&a)
#define print(a) printf("%d",a)
#define printn(a) printf("%d
",a)
using namespace std;
int n,m;
bool prime[MAXN];
void init()
{
scanf(n); scanf(m);
memset(prime,true,n+1);
prime[0]=false; prime[1]=false;
}
void f_prime()
{
for (int i=2;i<=n;i++)
{
for (int j=i+i;j<=n;j+=i)
{
prime[j]=false;
}
}
}
void start()
{
f_prime();
for (int i=1,a;i<=m;i++)
{
scanf(a);
if (prime[a])
{
printf("Yes
");
continue;
}
printf("No
");
}
}
int main()
{
init();
start();
return 0;
}
3.欧拉筛法
算是个埃筛的优化……但是常数比较大
我们发现此方法还可以继续优化,因为上述的方法中,每一个有多组因数可能会被筛多次
即一个合数(x)与一个质数(y)的乘积可以表示成一个更大的合数(Z)与一个更小的质数(a)的乘积
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define MAXN 10000005
#define MAXM
#define scanf(a) scanf("%d",&a)
#define print(a) printf("%d",a)
#define printn(a) printf("%d
",a)
using namespace std;
int n,m,tot=0;
bool prime[MAXN];
int P[MAXN];
void init()
{
scanf(n); scanf(m);
memset(prime,true,sizeof(prime));
prime[0]=false; prime[1]=false;
}
void f_prime()
{
for (int i=2;i<=n;i++)
{
if (prime[i])
{
P[++tot]=i;
}
for (int j=1;j<=tot&&i*P[j]<=n;j++)
{
prime[i*P[j]]=false;
if (!(i%P[j]))
{
break;
}
}
}
}
void start()
{
f_prime();
for (int i=1,a;i<=m;i++)
{
scanf(a);
if (prime[a])
{
printf("Yes
");
continue;
}
printf("No
");
}
}
int main()
{
init();
start();
return 0;
}
(yxy的黑历史:在jzwc的摸底比赛中 可以暴力过的判断素数 我打了个超大的表(((()
(谨以此时刻提醒自己。。。自己太菜了所以要更努力)