remainder solution for large numbers

Big numbers out of bounds

When a increases, finally Han Hui's 3 a 3^a3The size of a grows exponentially, which may exceed the value range of int32 or even int64, resulting in an error in the return value.

Large number remainder problem: under the premise of only using int32 type storage, correctly calculate xax^axRemainder of a to p (ie xax^a % pxa ⊙ p) problem.

Solution: Cyclic remainder, fast power remainder, the latter has lower time complexity, both methods are introduced based on the following remainder operation rules

( xy ) ⊙ p = [ ( x ⊙ p ) ( y ⊙ p ) ] ⊙ p (xy)⊙p=[(x⊙p)(y⊙p)]⊙p(xy)p=[(xp ) ( andp)]p

1. Cyclic remainder:

  • According to the nature of the remainder operation (∵ in this question x < p x < px<p,∴ x ⊙ p = x x⊙p=x xp=x ):

x a ⊙ p = [ ( x a − 1 ⊙ p ) ( x ⊙ p ) ] ⊙ p = [ ( x a − 1 ⊙ p ) x ] ⊙ p x^a⊙p=[(x^{a-1}⊙p)(x⊙p)]⊙p=[(x^{a-1}⊙p)x]⊙p xap=[(xa1p)(xp)]p=[(xa1p)x]p

  • Analysis: Using this formula, you can find x 1 , x 2 , x 3 , . . . xa − 1 x^1,x^2,x^3,...x^{a-1} in sequence through loop operationx1,x2,x3,...xFor the remainder of a 1 to p, the intermediate value of each round is guaranteed to be within the range of int32 values. The code of the encapsulation method is as follows.
  • Time complexity O ( N ) O(N)O ( N ) : where N=a, which is the linear complexity of the loop.
// (x^a) % p —— 循环求余法
int remainder(int x,int a,int p):
{
    
    
	int rem = 1;
	for(int i=0:i < a;i++){
    
    
		rem = (rem * x) % p;
	}
	return rem;
}

2. Fast power remainder:

  • According to the nature of the remainder operation, it can be deduced that:
  • x a ⊙ p = ( x 2 ) a / 2 ⊙ p = ( x 2 ⊙ p ) a / 2 ⊙ p x^a⊙p=(x^2)^{a/2}⊙p=(x^2⊙p)^{a/2}⊙p xap=(x2)a/2p=(x2p)a/2p
  • When a is an odd number, a/2 is not an integer, so it is divided into the following two cases, ("//" represents division rounded down):
    xa ⊙ p = { ( x 2 ⊙ ) a / / 2 ⊙ p , a is an even number [ ( x ⊙ p ) ( xa − 1 ⊙ p ) ] ⊙ p = [ x ( x 2 ⊙ p ) a / / 2 ] ⊙ p , a is an odd number x^a⊙p= \begin{cases} (x^2⊙)^{a//2}⊙p,& \text{a is an even number}\\[5ex] [(x⊙p)(x^{a-1}⊙p)]⊙p= [x(x^2⊙p)^{a//2}]⊙p, &\text{a is an odd number} \end{cases}xap=(x2)a//2p,[(xp)(xa1p)]p=[x(x2p)a//2]p,a is an even numbera is an odd number
  • Analysis : Using the above formula, the index a problem can be reduced to the index a//2 problem each time through the loop operation, only need to loop log 2 ( N ) log2(N)l o g 2 ( N ) times, so the complexity can be reduced to logarithmic level. The encapsulation method code is as follows:
int reminder(int x,int a,int p)
{
    
    
	int rem = 1;
	while(a > 0){
    
    
		if (a % 0){
    
    
			rem = (rem * x) % p;
		}
		x = x ^ 2 % p;
		a //=2;
	}
	return rem;
}
  • Help to understand: According to the following table, the initial state rem = 1 , x = 3 , a = 19 , p = 1000000007 , rem=1,x=3,a=19,p=1000000007,rem=1,x=3,a=19,p=1 0 0 0 0 0 0 0 0 7 , finallyrem ∗ ( xa ⊙ p ) rem*(x^a⊙p)remxap ) intorem ∗ ( xa ⊙ p ) = rem ∗ 1 rem*(x^a⊙p)=rem*1rem(xap)=rem1 in the form ofrem remr e m is the remainder answer.
    -insert image description here

Guess you like

Origin blog.csdn.net/qq_43679351/article/details/124902841