Loading [MathJax]/jax/output/CommonHTML/jax.js

Peter's codebook A blog full of codes

POJ 3641 Pseudoprime numbers

Prime!

傳送門

POJ3641

題目概述

求出題目定義的 Pseudoprime。 若 p 不是質數,但對於某個 a 和 前述的 p ,有 ap=a(modp) 的特性,稱 p 是 base-a 的 Pseudoprime。

解題想法

先建質數表,先判斷 p 是否為質數,再判斷是否有 ap=a(modp)

程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstdlib>
using namespace std;

typedef long long int UT;
const size_t MAXN=100000;
vector<int>plist;
bool is_prime[MAXN];

void mk_prime() {
    fill(is_prime, is_prime+MAXN, true);
    is_prime[1]=is_prime[0]=false;
    plist.push_back(2);
    for(int i=3; i<MAXN; i+=2) {
        if(is_prime[i]) {
            plist.push_back(i);
            for(int j=i+i; j<MAXN; j+=i) is_prime[j]=false;
        }
    }
}

inline bool is_p(int n) {
    if(n==2) return true;
    if(n%2==0) return false;
    if(n<MAXN) return is_prime[n];
    for(vector<int>::iterator v=plist.begin(); v!=plist.end() && (*v)*(*v)<=n; ++v) {
        if(n%(*v)==0) return false;
    }
    return true;
}

bool fastpow(UT a, UT p) {
    if(is_p(p)) return false;
    UT P=p;
    UT t=a, res=1uLL;
    while(p>0uLL) {
        if(p&1uLL) {
            res = (res*t)%P;
        }
        t=(t*t)%P;
        p>>=1uLL;
    }
    return res%P==a;
}

int main(void) {
    UT a,p;
    mk_prime();
    while(scanf("%lld%lld",&p,&a)==2 ) {
        if(p==0uLL&&a==0uLL)break;
        printf(fastpow(a,p)?"yes\n":"no\n");
    }
    return 0;
}