1.欧拉函数
(1)欧拉函数
欧拉函数:1~n中与n互质的数的个数
互质:两个数的公约数只有1
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
while(n -- > 0){
int x = sc.nextInt();
int res = x;
for(int i = 2; i <= x / i; i ++){//分解质因数的模板
if(x % i == 0){
res = res / i * (i - 1);//欧拉函数的公式,先除再乘防止溢出
}
while(x % i == 0){
x /= i;
}
}
if(x > 1) res = res / x * (x - 1);
System.out.println(res);
}
}
}
(2)筛法求欧拉函数
质数i的欧拉函数即为phi[i] = i - 1
import java.util.*;
public class Main{
static int N = 1000010;
static int[] phi = new int[N];
static int[] pr = new int[N];
static boolean[] st = new boolean[N];
//在线性筛的过程中求欧拉函数
public static void get_euler(int n){
phi[1] = 1;
int cnt = 0;
for(int i = 2; i <= n; i ++){
if(!st[i]){//在这个if里的都是质数
pr[cnt ++] = i;
phi[i] = i - 1;//一个质数与所有小于它的数都互质
}
for(int j = 0; pr[j] <= n / i; j ++){
st[pr[j] * i] = true;
if(i % pr[j] == 0){
phi[i * pr[j]] = pr[j] * phi[i];//由公式推导而来
break;
}
phi[i * pr[j]] = (pr[j] - 1) * phi[i];//公式推导
}
}
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
get_euler(n);
long res = 0;
for(int i :phi){
res += i;//把每个数的欧拉函数相加
}
System.out.print(res);
}
}
2.快速幂
(1)快速幂
import java.io.*;
import java.util.*;
public class Main{
public static int quick(int a, int k, int p){
int res = 1;
while(k != 0){
if((k & 1) == 1){//k与1,判断k的二进制的最后一位是不是1,如果是的话执行下面的操作
res = (int)((long) res * a % p);
}
k >>= 1;//将k的二进制向右移动一位,以便下一次的判断
a = (int)((long)a * a % p);//把a的多少次方先算出来,每次循环的a都是在上一次a的基础上变化的
}
return res;
}
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
while(n -- > 0){
String[] str = br.readLine().split(" ");
int a = Integer.parseInt(str[0]);
int k = Integer.parseInt(str[1]);
int p = Integer.parseInt(str[2]);
System.out.println(quick(a, k, p));
}
}
}
(2)快速幂求逆元
涉及到费马定理 b^(p-1) = 1 (mod p),分解得到 b * b^(p - 2) = 1 (mod p)
import java.util.*;
public class Main{
public static int quick(int a, int k, int p){
int res = 1;
while(k != 0){
if((k & 1) == 1) res = (int)((long)res * a % p);
k >>= 1;
a = (int)((long)a * a % p);
}
return res;
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
while(n -- > 0){
int a = sc.nextInt();
int p = sc.nextInt();
int res = quick(a, p - 2, p);
//a与p互质才能用费马定理的公式
if(a % p != 0) System.out.println(res);
else System.out.println("impossible");
}
}
}
3.扩展欧几里得算法
(1)扩展欧几里得算法
裴蜀定理:对于任意两个正整数a,b,一定存在非零整数x,y,使得ax + by = a和b的最大公约数。
import java.util.*;
import java.io.*;
public class Main{
static int[] x = new int[1], y = new int[1];
public static int exgcd(int a, int b, int[] x, int[] y){
if(b == 0){
//如果b等于0,那么gcd(a,b)就等于a,所以ax + 0y = a 则 x = 1,y = 0
x[0] = 1;
y[0] = 0;
return a;
}else{
//由欧几里得算法得:gcd(a,b) = gcd(b,a % b)
//ax + by = gcd(a,b), bx + (a % b)y = gcd(b,a % b)
//所以 by + (a % b)x = gcd(a,b)
//由(a % b ) = a - (a / b) * b
//得by + (a - (a / b) * b)x = gcd(a,b)
//故ax + b(y - (a / b) * x) = gcd(a,b)
int d = exgcd(b, a % b, y, x);
y[0] -= (a / b) * x[0];
return d;
}
}
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
while(n -- > 0){
String[] str = br.readLine().split(" ");
int a = Integer.parseInt(str[0]);
int b = Integer.parseInt(str[1]);
exgcd(a, b, x, y);
System.out.println(x[0] + " " + y[0]);
}
}
}
(2)线性同余方程
import java.util.*;
public class Main{
static int[] x = new int[1], y = new int[1];
public static int gcd(int a, int b, int[] x, int[] y){
if(b == 0){
x[0] = 1;
y[0] = 0;
return a;
}
int d = gcd(b, a % b, y, x);
y[0] -= (a / b) * x[0];
return d;
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
while(n -- > 0){
int a = sc.nextInt();
int b = sc.nextInt();
int m = sc.nextInt();
int d = gcd(a, m, x, y);
if(b % d != 0) System.out.println("impossible");
else System.out.println((long)x[0] * b / d % m);
}
}
}
4.中国剩余定理
AcWing 204. 表达整数的奇怪方式 - AcWing
这个太难le,过几天回来补