萌新刚学素数0.1ms,求助Miller_Rabin,WA了
查看原帖
萌新刚学素数0.1ms,求助Miller_Rabin,WA了
895690
gghack_Nythix楼主2023/10/3 22:15

rt

#include<bits/stdc++.h>
#define int long long
using namespace std;
int ksc(int x,int y,int mod){//我也不知道这是个什么快速乘法模板 
    int c = (long double)x / mod * y;
    int ret = (unsigned int)x * y - (unsigned int)c * mod;
    return (ret + mod) % mod;
}
int ksm(int a,int b,int mod){//快速幂模板 
    int ans = 1;
    while(b){
        if(b & 1)ans = ksc(ans,a,mod);
        a = ksc(a,a,mod);
        b >>= 1;
    }
    return ans;
}
bool Miller_Rabin(int n){
    if(n < 3 || n % 2 == 0)return n == 2;
    int u = n - 1,t = 0;
    while(!u % 2)u /= 2,++t;
    int ds[] = {2,325,9375,28178,450775,9780504,1795265022};//多几个底数保证100%正确 
    for(register int i = 0;i < 7;++i){
        int nowds = ds[i];
        int v = ksm(nowds,u,n);//二次探测定理 
        if(v == 1 || v == n - 1 || v == 0)continue;//探测出来发现这个底数明显满足二次探测定理结果直接换底数 
        for(register int j = 1;j <= t;++j){//之前拆成了几次方 
            v = ksc(v,v,n);
            if(v == n - 1 && j != t){v = 1;break;}//测出来发现这个底数明显满足二次探测而且不是最后一个拆出来的定理结果直接换底数  
            if(v == 1) return 0;//没有一次出现了n - 1这个解证明不满足二次探测定理 
        }
        if(v != 1)return 0;//不满足二次探测定理 
    }
    return 1;
}
signed main(){
    //调用Miller_Rabin(n)返回n是否是质数
    ios::sync_with_stdio(false);
    cin.tie(0); 
    int n,ans = 0;
    cin >> n;
    for(register int i = 1;i <= n;++i){
        if(Miller_Rabin(i))++ans;
    }
    cout << ans << '\n';
    return 0;
}
2023/10/3 22:15
加载中...