Let's start with an explanation of what is fast exponentiation
Then after understanding what fast exponentiation is, what I want to write here is an application of it, including the method of calculating interval prime numbers by the Ehrlich sieve method.
For the sieve method, you can see my other blog http://blog.csdn.net/qq_34115899/article/details/79498829
Title: Carmichael Numbers (UVa No.10006)
The general meaning is: we call the composite number n that x n ≡ x(mod n) holds for any 1<x< n as Carmichael Numbers. For a given integer n, determine whether it is Carmichael Numbers. (Note: the remainders obtained after dividing a and b by m are equal and denoted as a≡b(mod m))
Constraints 2<n<65000
Example:
Enter: Enter: Enter: Enter: Enter: Enter:
17 561 4 1729 1109 431
output: output: output: output: output: output:
NO YES NO YES NO NO
import java.util.Scanner; /* Can be written in any language without using language features */ public class Main { public static boolean[] is_prime = new boolean[65001]; public static void main(String[] args) { Scanner cin = new Scanner(System.in); long n = cin.nextLong(); cin.close(); boolean flag = true; sieve(n); // record within n, which are prime numbers if (is_prime[(int) n]) { // it's not a good idea if it's a prime number flag = false; } else { for (int i = 2; i < n; ++i) { // 1<x<n has xn≡x(mod n), that is, xn mod n from 1~n is always equal to x mod n, Satisfaction is YES otherwise NO if (mod_pow(i, n, n) != i % n) { flag = false; break; } } } if (flag) { System.out.println("YES"); } else { System.out.println("NO"); } } /*Principle of the sieve method: first write down all integers in the range of 2 to n. The smallest number, 2, is a prime number. Cross out all multiples of 2 in the table. The smallest number remaining in the table is 3, which is not divisible by smaller numbers, so it is prime. Then cross out all multiples of 3 in the table. And so on, if the smallest number remaining in the table is m, then m is prime. Then cross out all multiples of m in the table. By repeating operations like this, you can enumerate the prime numbers within n in turn */ public static void sieve(long n) { // The sieve complexity O(nlognlogn) can also be regarded as linear is_prime[0] = is_prime[1] = false; for (int i = 2; i <= n; ++i) { is_prime[i] = true; } for (int i = 2; i <= n; ++i) { if (is_prime[i]) { for (int j = i << 1; j <= n; j += i) { is_prime[j] = false; } } } } public static long mod_pow(long x, long n, long mod) { // java's long is 64 bits, c++'s long long is 64 bits, long is 32 bits long res = 1; while (n > 0) { if ((n & 1) == 1) { res = res * x % mod; } x = x * x % mod; n >>= 1; } return res; } }
Next, if you use the Java language feature to use BigInteger, it is very convenient, but it may time out
import java.math.BigInteger; import java.util.Scanner; public class Main { public static boolean[] is_prime = new boolean[65001]; public static void main(String[] args) { Scanner cin = new Scanner(System.in); int n = cin.nextInt (); cin.close(); boolean flag = true; sieve(n); if (is_prime[n]) { flag = false; } else { for (int i = 2; i < n; ++i) { BigInteger ii = new BigInteger(i + ""); if (ii.pow(n).mod(new BigInteger(n + "")).intValue() != i % n) { flag = false; break; } } } if (flag) { System.out.println("YES"); } else { System.out.println("NO"); } } public static void sieve(long n) { is_prime[0] = is_prime[1] = false; for (int i = 2; i <= n; ++i) { is_prime[i] = true; } for (int i = 2; i <= n; ++i) { if (is_prime[i]) { for (int j = i << 1; j <= n; j += i) { is_prime[j] = false; } } } } }
============================== I am a slow programmer ============= =============