5.3 每日一题题解

小道消息

涉及知识点:

  • 质数/思维

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;
}

猜你喜欢

转载自www.cnblogs.com/QFNU-ACM/p/12821416.html
5.3