Find the number of primitive roots modulo prime in C++.

C++Server Side ProgrammingProgramming

In this problem, we are given a prime number N. Our task is to find the number of primitive roots modulo prime.

Primitive Root of a number − It is a number (r) smaller than N which has all values of r^x(mod N) different for all X in range [0, n-2].

Let’s take an example to understand the problem,

Input : N = 5
Output : 2

Solution Approach

A simple solution to the problem is based on a trial method. We will check for all numbers from 2 to (N-1) for the conditions with x ranging from [0, n-2] and break if a value is found that satisfies the condition.

This solution is naive and is easy to implement but the time complexity of the solution is of the order of N2. This might lead to long runs in case of a large value of N.

So, a more efficient solution to the problem is by using the Euler Totient function φ(N)

So, for a number r to be the primitive root of N. Its multiplicative order with modulo N is equal to φ(N). Here are steps to follow −

We need to find all prime factors of (N-1) for the prime number N. Then calculate all powers using (N-1) / prime factors. Then check the value of prime numbers power modulo n. If its is never 1 then i is the primitive root. The first value which we see will be the returned value as there can be more than one primitive root for a number but we need only the smallest one.

Example

Let’s take an example to understand the problem

#include<bits/stdc++.h>
using namespace std;
int calcPowerMod(int x, unsigned int y, int p){
   int modVal = 1;
   x = x % p;
   while (y > 0){
      if (y & 1)
         modVal = (modVal*x) % p;
      y = y >> 1;
      x = (x*x) % p;
   }
   return modVal;
}
void findAllPrimeFactors(unordered_set<int> &s, int n){
   while (n%2 == 0){
      s.insert(2);
      n = n/2;
   }
   for (int i = 3; i*i <= n; i = i+2){
      while (n%i == 0){
         s.insert(i);
         n = n/i;
      }
   }
   if (n > 2)
      s.insert(n);
}
int findSmallestPrimitiveRoot(int n){
   unordered_set<int> primes;
   int phi = n-1;
   findAllPrimeFactors(primes, phi);
   for (int r=2; r<=phi; r++){
      bool flag = false;
      for (auto it = primes.begin(); it != primes.end(); it++){
         if (calcPowerMod(r, phi/(*it), n) == 1){
            flag = true;
            break;
         }
      }
      if (flag == false)
         return r;
   }
   return -1;
}
int main(){
   int n = 809;
   cout<<"The smallest primitive root is "<<findSmallestPrimitiveRoot(n);
   return 0;
}

Output

The smallest primitive root is 3
raja
Updated on 24-Jan-2022 13:34:13

Advertisements