2 条题解

  • 0
    @ 2025-10-8 17:11:26
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring> 
    #include <cmath> 
    #include <algorithm>
    #include <ctime> 
    using namespace std;
    typedef long long ll; 
    const int MAX_N = 1e7 + 5; 
    const int T = 10; 
    bool is_prime[MAX_N]; 
    int prime[MAX_N], num, K;
    ll N = 1e7, ans[MAX_N], cnt_ans; 
    void sieve() { 
        for (int i = 1; i <= N; i++) is_prime[i] = 1; 
        is_prime[1] = 0; 
        for (int i = 2; i <= N; i++) { 
            if (is_prime[i]) prime[++num] = i; 
            for (int j = 1; prime[j] * i <= N && j <= num; j++) { 
                is_prime[i * prime[j]] = 0;
                if (!(i % prime[j])) break; 
            } 
        } 
    } 
    ll fmul(ll x, ll y, ll Mod) {
        ll res = 0;
        while (y) {
            if (y & 1ll) res = (res + x) % Mod; 
            y >>= 1ll; 
            x = (x + x) % Mod; 
        }
        return res; 
    } 
    ll fpow(ll x, ll y, ll Mod) {
        ll res = 1; 
        while (y) {
            if (y & 1ll) res = fmul(res, x, Mod);
            y >>= 1ll; 
            x = fmul(x, x, Mod); 
        }
        return res; 
    } 
    bool Test(ll a, ll n) {
        ll r = 0, t = n - 1, m; 
        while ((t & 1ll) == 0) ++r, t >>= 1ll;
        m = (n - 1) / (1ll << r); 
        for (int i = 0; i < r; i++) if (fpow(a, (1ll << i) * m, n) == n - 1) return 1;
        if (fpow(a, m, n) == 1) return 1; 
        return 0; 
    } 
    bool Miller_Rabin(ll n) {
        if (n == 2ll) return 1; 
        if (n < 2ll || ((n & 1ll) == 0)) return 0; 
        for (int i = 1; i <= T; i++) { 
            ll a = rand() % (n - 2) + 2;
            if (fpow(a, n - 1, n) != 1) return 0;
            if (!Test(a, n)) return 0; 
        }
        return 1; 
    }
    void solve(ll phi, ll n, int lst) { 
        if (phi + 1 > prime[num] && Miller_Rabin(phi + 1))
            ans[++cnt_ans] = n * (phi + 1); 
        for (int i = lst; i; i--) {
            if (!(phi % (prime[i] - 1))) {
                ll t1 = phi / (prime[i] - 1), t2 = n, t3 = 1ll; 
                while (!(t1 % t3)) { 
                    t2 *= prime[i];
                    solve(t1 / t3, t2, i - 1); 
                    t3 *= prime[i]; 
                } 
            } 
        }
        if (phi == 1ll) ans[++cnt_ans] = n; 
    } 
    int main () {
        srand(time(NULL)); 
        sieve(); 
        cin >> N >> K;
        solve(N, 1ll, num); 
        sort(&ans[1], &ans[cnt_ans + 1]);
        for (int i = 1; i < K; i++) printf("%lld ", ans[i]);
        printf("%lld\n", ans[K]); 
        return 0; 
    } 
    
    • 0
      @ 2025-10-8 17:11:18
      #include <iostream>
      #include <cstdio>
      #include <cstdlib>
      #include <cstring> 
      #include <cmath> 
      #include <algorithm>
      #include <ctime> 
      using namespace std;
      typedef long long ll; 
      const int MAX_N = 1e7 + 5; 
      const int T = 10; 
      bool is_prime[MAX_N]; 
      int prime[MAX_N], num, K;
      ll N = 1e7, ans[MAX_N], cnt_ans; 
      void sieve() { 
      	for (int i = 1; i <= N; i++) is_prime[i] = 1; 
      	is_prime[1] = 0; 
      	for (int i = 2; i <= N; i++) { 
      		if (is_prime[i]) prime[++num] = i; 
      		for (int j = 1; prime[j] * i <= N && j <= num; j++) { 
      			is_prime[i * prime[j]] = 0;
      			if (!(i % prime[j])) break; 
      		} 
      	} 
      } 
      ll fmul(ll x, ll y, ll Mod) {
      	ll res = 0;
      	while (y) {
      		if (y & 1ll) res = (res + x) % Mod; 
      	    y >>= 1ll; 
      		x = (x + x) % Mod; 
      	}
      	return res; 
      } 
      ll fpow(ll x, ll y, ll Mod) {
      	ll res = 1; 
      	while (y) {
      		if (y & 1ll) res = fmul(res, x, Mod);
      		y >>= 1ll; 
      		x = fmul(x, x, Mod); 
      	}
      	return res; 
      } 
      bool Test(ll a, ll n) {
      	ll r = 0, t = n - 1, m; 
      	while ((t & 1ll) == 0) ++r, t >>= 1ll;
      	m = (n - 1) / (1ll << r); 
      	for (int i = 0; i < r; i++) if (fpow(a, (1ll << i) * m, n) == n - 1) return 1;
      	if (fpow(a, m, n) == 1) return 1; 
      	return 0; 
      } 
      bool Miller_Rabin(ll n) {
      	if (n == 2ll) return 1; 
      	if (n < 2ll || ((n & 1ll) == 0)) return 0; 
      	for (int i = 1; i <= T; i++) { 
      		ll a = rand() % (n - 2) + 2;
      		if (fpow(a, n - 1, n) != 1) return 0;
      		if (!Test(a, n)) return 0; 
      	}
      	return 1; 
      }
      void solve(ll phi, ll n, int lst) { 
      	if (phi + 1 > prime[num] && Miller_Rabin(phi + 1))
      		ans[++cnt_ans] = n * (phi + 1); 
      	for (int i = lst; i; i--) {
      		if (!(phi % (prime[i] - 1))) {
      			ll t1 = phi / (prime[i] - 1), t2 = n, t3 = 1ll; 
      			while (!(t1 % t3)) { 
      				t2 *= prime[i];
      				solve(t1 / t3, t2, i - 1); 
      				t3 *= prime[i]; 
      			} 
      		} 
      	}
      	if (phi == 1ll) ans[++cnt_ans] = n; 
      } 
      int main () {
      	srand(time(NULL)); 
      	sieve(); 
      	cin >> N >> K;
      	solve(N, 1ll, num); 
      	sort(&ans[1], &ans[cnt_ans + 1]);
      	for (int i = 1; i < K; i++) printf("%lld ", ans[i]);
      	printf("%lld\n", ans[K]); 
      	return 0; 
      } 
      
      • 1

      【大素数测试算法Miller_Rabin】逆欧拉函数

      信息

      ID
      6472
      时间
      1000ms
      内存
      256MiB
      难度
      10
      标签
      递交数
      2
      已通过
      2
      上传者