SPOJ PROOT - Primitive Root

题目链接http://www.spoj.com/problems/PROOT/

题目大意:给出一个整数p,p为素数,给出n个数x,判断x是否为p的原根。

解题思路:参考:http://www.apfloat.org/prim.html 

大致思想:如果x是模p的原根,那么 ep(x) = p - 1, 否则 ep(x) 整除 p - 1。 而如果从1到p-1判断x的幂是否为1显然太耗费时间,实际上是只需要判断对于每个 p - 1的质因子 f 来说,是否有 x (p - 1) / f ≡ 1 (mod p) 即可。

代码:

 1 const int maxn = 1e5 + 5;
 2 ll p;
 3 int n;
 4 VI factors, primes;
 5 bool vis[maxn];
 6 
 7 void dowork(){
 8     for(int i = 2; i < maxn; i++){
 9         if(!vis[i])
10             for(int j = i * 2; j > 0 && j < maxn; j += i)
11                 vis[j] = 1;
12     }
13     for(int i = 2; i < maxn; i++)
14         if(!vis[i]) primes.push_back(i);
15 }
16 void getf(){
17     factors.clear();
18     int x = p - 1;
19     for(int i = 0; i < primes.size(); i++){
20         int u = primes[i];
21         if(x % u == 0) factors.push_back(u);
22         while(x % u == 0) x /= u;
23     }
24 }
25 ll pow_mod(ll a, ll b, ll m){
26     ll ans = 1, base = a % m;
27     while(b){
28         if(b & 1) ans = ans * base % m;
29         base = base * base % m;
30         b >>= 1; 
31     }
32     return ans % m;
33 }
34 bool check(int x){
35     for(int i = 0; i < factors.size(); i++){
36         int u = (p - 1) / factors[i];
37         int tmp = pow_mod(x, u, p);
38         if(tmp == 1) return false;
39     }
40     return true;
41 }
42 int main(){
43     dowork();
44     while(scanf("%lld %d", &p, &n) && p){
45         getf();
46         for(int i = 1; i <= n; i++){
47             int x;
48             scanf("%d", &x);
49             if(check(x)) puts("YES");
50             else puts("NO");
51         }
52     }
53 }

题目:

PROOT - Primitive Root

no tags 

 

In the field of Cryptography, prime numbers play an important role. We are interested in a scheme called "Diffie-Hellman" key exchange which allows two communicating parties to exchange a secret key. This method requires a prime number p and r which is a primitive root of p to be publicly known. For a prime number p, r is a primitive root if and only if it's exponents r, r2, r3, ... , rp-1 are distinct (mod p).

Cryptography Experts Group (CEG) is trying to develop such a system. They want to have a list of prime numbers and their primitive roots. You are going to write a program to help them. Given a prime number p and another integer r < p , you need to tell whether r is a primitive root of p.

Input

There will be multiple test cases. Each test case starts with two integers p ( p < 2 31 ) and n (1 ≤ n ≤ 100 ) separated by a space on a single line. p is the prime number we want to use and n is the number of candidates we need to check. Then n lines follow each containing a single integer to check. An empty line follows each test case and the end of test cases is indicated by p=0 and n=0 and it should not be processed. The number of test cases is atmost 60.

Output

For each test case print "YES" (quotes for clarity) if r is a primitive root of p and "NO" (again quotes for clarity) otherwise.

Example

Input:
5 2
3
4

7 2
3
4

0 0


Output:
YES
NO
YES
NO

Explanation

In the first test case 31, 32 , 33 and 34 are respectively 3, 4, 2 and 1 (mod 5). So, 3 is a primitive root of 5.

41, 42 , 43 and 44 are respectively 4, 1, 4 and 1 respectively. So, 4 is not a primitive root of 5.

posted @ 2017-09-12 20:31  EricJeffrey  阅读(337)  评论(0编辑  收藏  举报