[Java] HDU 1576 (Fermat's Small Theorem + Extended Euclidean)

Keywords: Java

Train of thought:
(A/B)% 9937 = A*B-1% 9973. Here B-1 represents the inverse element of multiplication, not 1/B.
Multiplication Inverse Element: A divided by a number modulus P, equal to A multiplied by this number of multiplication inverse element modulus P.

So we only need to solve the multiplication inverse B-1 of B for 9973.

Solution 1: Fermat's Small Theorem for Multiplication Inverse Element
If A is an integer and B is a prime, then ab_a(mod b) or ab-1_1 (mod b)
It can be concluded from the expansion of Euclidea that:
Because GCD (a, b) = 1, ax_1 (mod b) x is the inverse element of multiplication
Ab-1 = a*a B-2 = a x_1(mod b). So x = ab-2 is the inverse element of multiplication. We can solve it by fast power.
Seek x = a9973-2 in this question.

Solution 2: Extended Euclidean

Because gcd(B,9973) == 1, Bx_1 (mod 9973) x is B-1, which is the inverse element of multiplication of B.
The x calculated by ex_gcd(B,9973) is B-1, and X may be negative, so we need to deal with it.

	static int x, y;
	static int ex_gcd(int a, int b) {
		if (b == 0) {
			x = 1;y = 0;
			return a;
		}
		int ans = ex_gcd(b, a % b);
		int tem = y;
		y = x - a / b * y;
		x = tem;
		return ans;
	}

Codes for two solutions:

import java.util.Scanner;

public class HDU_1576 {
	static int n, b;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int t = sc.nextInt();
		while (t-- > 0) {
			n = sc.nextInt();
			b = sc.nextInt();
			//System.out.println(f1(b, 9973) * n % 9973);
			System.out.println(f2(b, 9973) * n % 9973);
		}
	}
	static int x, y;
	static int ex_gcd(int a, int b) {
		if (b == 0) {
			x = 1;y = 0;
			return a;
		}
		int ans = ex_gcd(b, a % b);
		int tem = y;
		y = x - a / b * y;
		x = tem;
		return ans;
	}
	
	//1. Solving multiplicative inverse elements by extending Euclidean
	static int f1(int a, int b) {
		int d = ex_gcd(a, b);
		int t = b / d;
		//Because the calculated x is possibly negative, use the general solution, so deal with it.
		x = (x % t + t) % t;
		return x;
	}
	
	//2. Solving inverse elements of multiplication by Fermat's small theorem
	static long f2(long a,long b) {
		//a * a^(b-2)  x = a^(b-2)
		b = b - 2;
		long ans = 1;
		while (b != 0) {
			if ((b & 1) == 1) {
				ans = (ans * a) % 9973;
			}
			a = (a * a) % 9973;
			b /= 2;
		}
		return ans;
	}
}

Posted by gmcalp on Mon, 07 Oct 2019 00:33:27 -0700