小道消息
涉及知识点:
solution:
- \(这个题可以暴力也可以套Miller-Rabin板子\)
- \(分情况考虑:\)
- \(第一种情况,k+1是质数:\)
- \(如果k+1是质数,那么第一天就可以感染所有与其互质的数\)
- \(第一种情况又可以分成两种小情况:\)
- \(举个例子,k = 4,n = 100,那么k+1 = 5,5是质数,但是5第一天无法感染5的倍数\)
- \(那么只需要第一天感染小于等于n的最大的质数,这样第二天就可以完全感染了\)
- \(但是如果k=4,n=8,5的倍数大于n,那么第一天就可以完全感染了\)
- \(第二种情况,k+1不是质数:\)
- \(我们只需要第一天感染最大的质数,第二天完全感染\)
- \(所以只需要判断k+1是不是质数即可,n=1e14,尝试sqrt(n)不会超时\)
- \(如果想更快,就套用Miller-Rabin板子,这是一个快速检测一个小于long long范围的数是否是素数\)
std:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
ll n , k;
int flag = 0;
cin>>n>>k;
k++;
for(ll i=2;i*i<=k;i++){
if(k%i == 0){
flag = 1;
break ;
}
}
if(flag){
cout<<"2"<<endl;
}else{
if((n+1)/2 >= k)
cout<<"2"<<endl;
else
cout<<"1"<<endl;
}
return 0;
}
Miller-Rabin模板:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll mod_exp(ll a,ll b,ll c)
{
ll m = 1;
while(b){
if(b&1) m = (m%c)*(a%c)%c;
b>>=1;
a=(a%c)*(a%c)%c;
}
return m;
}
bool miller_rabbin(ll a)
{
if(a == 2)
return true;
ll i,j;
for(i=0;i<20;i++)
{
j = rand()%(a-2)+2;
if(mod_exp(j,a-1,a)!=1)
return false;
}
return true;
}
int main()
{
ll n;
cin>>n;
if(miller_rabbin(n)){
printf("isprime\n");
}else{
printf("not prime\n");
}
return 0;
}