注意:以下部分内容摘自Acwing,仅用于个人学习记录,不做任何商业用途。
一、质数
(1)试除法判定质数
重点在 i 的循环终止条件:i <= n / i ,一定是小于等于 <= !!!
此外,必须判断n是否小于2
bool is_prime(int n){
if(n < 2) return false;
for(int i = 2;i <= n / i;i ++){ //优化内容
if(n % i == 0){
return false;
}
}
return true;
}
(2)筛质法
线性筛质法:(没看懂mad)
参考链接:AcWing 868. 对于——筛质数——三种方法的解释 - AcWing
void get_primes(){
for(int i=2;i<=n;i++){
if(!st[i])primes[cnt++]=i;
for(int j=0;primes[j]<=n/i;j++){
st[primes[j]*i]=true;
if(i%primes[j]==0)break;
}
}
}
二、约数
(1)试除法求约数
主要是注意list如何排序 的问题(记得去重)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
public class Main {
static void divisors(int x) {
ArrayList<Integer> list=new ArrayList<>();
for(int i=1;i<=x/i;i++) {
if(x % i == 0){
list.add(i);
if(x / i != i)list.add(x / i);
}
}
Collections.sort(list, (a, b)->a - b);
int r=-1;
for(int c : list){
if(r!=c)
System.out.print(c + " ");
r=c;
}
System.out.println();
}
public static void main(String[] args) throws IOException {
BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
int n=Integer.parseInt(br.readLine());
for (int i=0;i<n;i++) {
int x=Integer.parseInt(br.readLine());
divisors(x);
}
}
}
(2)求约数个数
所以先用一中的方法求出质数及其个数,再相乘。
(3)约数之和
(4)最大公约数
辗转相除法
cin >> a >> b;
//辗转相除,直到小括号内右边数为0
while(b)
{
//c 一定小于 b
int c = a % b;
//小括号左边放除数,右边放约数
a = b;
b = c;
}
//小括号内左边数为最大公约数
cout << a << endl;
三、欧拉函数
欧拉函数的定义:
cin>>a;
res = a;
for(int i=2;i<=a/i;i++)
{
if(a%i==0)
{
while(a%i==0)
a/=i;
res = res / i*(i-1);
}
}
if(a>1) res = res /a*(a-1);
cout<<res<<endl;
优化:
void get_eulers(int n)
{
phi[1] = 1;
for (int i = 2; i <= n; i++)
{
if (!st[i])
{
primes[cnt++] = i;
phi[i] = i - 1;
}
for (int j = 0; primes[j] <= n / i; j++)
{
st[primes[j] * i] = true;
if (i % primes[j] == 0)
{
phi[primes[j] * i] = phi[i] * primes[j];
break;
}
phi[primes[j] * i] = phi[i] * (primes[j] - 1);
}
}
}
作者:番茄酱
链接:https://www.acwing.com/solution/content/3952/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
四、快速幂
快速幂:快速求a^b% p的问题,时间复杂度:O(logb),若对于n组数据,那么时间复杂度为O(n∗logb)
思路:
五、扩展欧几里得算法
详见:AcWing 877. 扩展欧几里得算法 - AcWing
题目:
六、组合数
(1)公式法求组合数
(2)费马小定理
AcWing 886. 费马小定理, 快速冥, 求组合数 II - AcWing
import java.io.*;
class Main{
static BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
static int N = 100010, p = (int) 1e9 + 7;
static int[] fact = new int[N], infact = new int[N];
public static int qmi(int a, int k, int p){
long res = 1;
while( k > 0){
if( (k & 1) != 0 ) res = res * a % p;
a =(int) ((long) a * a % p);
k >>= 1;
}
return (int) res;
}
public static void main(String[] args) throws Exception{
int t = Integer.valueOf(read.readLine());
fact[0] = infact[0] = 1;
for(int i = 1; i < N; i++){
fact[i] =(int) ((long)fact[i - 1] * i % p);
infact[i] = (int) ((long) infact[i - 1] * qmi(i, p - 2, p ) % p);
}
while(t -- > 0){
String[] ss = read.readLine().split(" ");
int a = Integer.valueOf(ss[0]);
int b = Integer.valueOf(ss[1]);
int res = (int) ((long) fact[a] * infact[a - b] % p * infact[b] % p);
System.out.println(res);
}
}
}