kyopro_library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub dyktr06/kyopro_library

:heavy_check_mark: test/library_checker/number_theory/primality_test.test.cpp

Depends on

Code

#define PROBLEM "https://judge.yosupo.jp/problem/primality_test"
#include <bits/stdc++.h>
using namespace std;

#include "../../../lib/math/rho.hpp"

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int q; cin >> q;
    while(q--){
        long long n; cin >> n;
        if(Rho::rabin_miller(n)){
            cout << "Yes" << "\n";
        }else{
            cout << "No" << "\n";
        }
    }
}
#line 1 "test/library_checker/number_theory/primality_test.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/primality_test"
#include <bits/stdc++.h>
using namespace std;

#line 2 "lib/math/rho.hpp"

/**
 * @brief Pollard's Rho
 * @docs docs/math/rho.md
 */

namespace Rho{
    unsigned long long mul(unsigned long long a, unsigned long long b, const unsigned long long mod) {
        long long ret = a * b - mod * (unsigned long long)(1.0L / mod * a * b);
        return ret + mod * (ret < 0) - mod * (ret >= (long long) mod);
    }

    bool rabin_miller(unsigned long long n){
        switch(n){
        case 0: // fall-through
        case 1: return false;
        case 2: return true;
        }

        if(n % 2 == 0) return false;
        vector<long long> A = {2, 325, 9375, 28178, 450775, 9780504, 1795265022};
        unsigned long long s = 0, d = n - 1;
        while(d % 2 == 0){
            s++;
            d >>= 1;
        }

        auto modpow = [](unsigned long long x, unsigned long long e, const unsigned long long mod) -> unsigned long long {
            unsigned long long ret = 1 % mod;
            x %= mod;
            while(e > 0){
                if(e & 1) ret = mul(ret, x, mod);
                x = mul(x, x, mod);
                e >>= 1;
            }
            return ret;
        };

        for(auto a : A){
            if(a % n == 0) return true;
            unsigned long long t, x = modpow(a, d, n);
            if(x != 1){
                for(t = 0; t < s; ++t){
                    if(x == n - 1) break;
                    x = mul(x, x, n);
                }
                if(t == s) return false;
            }
        }
        return true;
    }

    mt19937_64 rng(chrono::system_clock::now().time_since_epoch().count());
    unsigned long long FindFactor(unsigned long long n) {
        if(n == 1 || rabin_miller(n)) return n;
        if(n % 2 == 0) return 2;
        unsigned long long c = 1, x = 0, y = 0, t = 0, prod = 2, x0 = 1, q;
        auto f = [&](unsigned long long X) { return mul(X, X, n) + c;};

        while(t++ % 128 or __gcd(prod, n) == 1) {
            if(x == y) c = rng() % (n - 1) + 1, x = x0, y = f(x);
            if((q = mul(prod, max(x, y) - min(x, y), n))) prod = q;
            x = f(x), y = f(f(y));
        }
        return __gcd(prod, n);
    }

    vector<unsigned long long> factorize(unsigned long long x) {
        if(x == 1) return {};
        unsigned long long a = FindFactor(x), b = x / a;
        if(a == x) return {a};
        vector<unsigned long long> L = factorize(a), R = factorize(b);
        L.insert(L.end(), R.begin(), R.end());
        return L;
    }

    vector<unsigned long long> divisor(unsigned long long x){
        vector<unsigned long long> factor = Rho::factorize(x);
        map<unsigned long long, int> countFactor;
        for(auto x : factor){
            if(countFactor.count(x) == 0) countFactor[x] = 0;
            countFactor[x]++;
        }
        vector<unsigned long long> ret = {1};
        for(auto [x, cnt] : countFactor){
            int n = ret.size();
            for(int i = 0; i < n; ++i){
                unsigned long long z = ret[i];
                for(int j = 0; j < cnt; ++j){
                    z *= x;
                    ret.push_back(z);
                }
            }
        }
        return ret;
    }
}
#line 6 "test/library_checker/number_theory/primality_test.test.cpp"

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int q; cin >> q;
    while(q--){
        long long n; cin >> n;
        if(Rho::rabin_miller(n)){
            cout << "Yes" << "\n";
        }else{
            cout << "No" << "\n";
        }
    }
}
Back to top page