Ninja420
Ninja420

Reputation: 3872

Finding pow(a^b)modN for a range of a's

For a given b and N and a range of a say (0...n),

I need to find ans(0...n-1) where,

ans[i] = no of a's for which pow(a, b)modN == i

What I am searching here is a possible repetition in pow(a,b)modN for a range of a, to reduce computation time.

Example:-

if b = 2 N = 3 and n = 5

for a in (0...4):
    A[pow(a,b)modN]++;

so that would be

pow(0,2)mod3 = 0
pow(1,2)mod3 = 1
pow(2,2)mod3 = 1
pow(3,2)mod3 = 0
pow(4,2)mod3 = 1

so the final results would be:

ans[0] = 2 // no of times we have found 0 as answer .

ans[1] = 3

...

Upvotes: 3

Views: 353

Answers (2)

Gerard Walace
Gerard Walace

Reputation: 921

Your algorithm have a complexity of O(n). Meaning it take a lot of time when n gets bigger.

You could have the same result with an algorithm O(N). As N << n it will reduce your computation time.

Firts, two math facts :

pow(a,b) modulo N == pow (a modulo N,b) modulo N

and

if (i < n modulo N)
   ans[i] = (n div N) + 1
else if (i < N)
   ans[i] = (n div N)
else
   ans[i] = 0

So a solution to your problem is to fill your result array with the following loop :

int nModN = n % N;
int nDivN = n / N;
for (int i = 0; i < N; i++)
{
    if (i < nModN)
        ans[pow(i,b) % N] += nDivN + 1;
    else
        ans[pow(i,b) % N] += nDivN;
}

Upvotes: 1

ugoren
ugoren

Reputation: 16441

You could calculate pow for primes only, and use pow(a*b,n) == pow(a,n)*pow(b,n).

So if pow(2,2) mod 3 == 1 and pow(3,2) mod 3 == 2, then pow(6,2) mod 3 == 2.

Upvotes: 0

Related Questions