【备战蓝桥杯】2024蓝桥杯赛前突击省一:基础数论篇

2024蓝桥杯赛前突击省一:基础算法模版篇

基础数论算法回顾

判断质数(试除法)

时间复杂度O(sqrt(n))

java 复制代码
static int is_prime(int n){
        if(n<2) return 0;
        for (int i=2;i<=n/i;i++){
            if(n%i==0) return 0;
        }
        return 1;
}

质因数分解

时间复杂度O(sqrt(n))

java 复制代码
static Map<Integer,Integer> mp = new TreeMap<>();//TreeMap有序
static void divide(int n){
    for(int i=2;i<=n/i;i++){
        int cnt = 0;//java里不能mp[i]++,所以用变量cnt存储,再赋值
        while(n%i==0){
            n/=i;
            cnt++;
        }
        mp.put(i,cnt);
    }
    if(n>1) mp.put(n,1);
}
//输出
for(Integer key:mp.keySet()){
    int val = mp.get(key);
    if(val>0)
        System.out.println(key+" "+mp.get(key));
}

素数筛

埃氏筛法

求n以内的所有素数

时间复杂度(O(nlogn))

java 复制代码
static int[] st;
static int[] primes;
static int cnt;

void get_primes(int n){
    for(int i=2;i<=n;i++){
        if(st[i]==0){
            primes[cnt++]=i;
            for(int j=i+i;j<=n;j+=i)
                st[j]=1;
        }
    }
    //求素数个数
    cnt	
}

线性筛

java 复制代码
void get_primes(int n)
{
    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;
        }
    }
}

求约数

时间复杂度 sqrt(n)

java 复制代码
	static ArrayList<Integer> yue = new ArrayList<>();   
	static void solve(int n){
        for (int i = 1; i <= n/i; i++) {
            if(n%i==0){
                yue.add(i);
                if(n/i!=i)
                    yue.add(n/i);
            }
        }
        Collections.sort(yue);//约数从小到达排
    }

求组合数

求C(a,b)

用long存!!!

  • N 在3000以内(题意不用取模)
java 复制代码
    static long[][] C = new long[N][N];
    static void init(){
        for (int i = 0; i < N; i++) {
            for (int j = 0; j <= i; j++) {
                if(j==0) C[i][j] = 1;
                else C[i][j] = C[i-1][j] + C[i-1][j-1];
                //对于要对答案取模的时候,在计算组合数的时候就要取模
                //else C[i][j] = (C[i-1][j] + C[i-1][j-1])%Mod;
            }
        }
    }
  • N在10^8以内、题目说要取模(用逆元求)

    C(a,b) = a!/(b! * (a-b)!) = a! * niyuan(b!) * niyuan((a-b)!)

    由于询问比较多,直接初始化阶乘和阶乘的逆元数组

    递推式:
    n! = (n-1)! * n
    1/(n!) = 1/(n-1)! * 1/n,其中1/n = qpow(n,Mod-2)(费马小定理)

java 复制代码
    //jiechen[i] = i!
    static long[] jiechen = new long[N];
    //jiechenniyuan[i] = "i!的逆元"
    static long[] jiechenniyuan = new long[N];

	//初始化阶乘、阶乘的逆元
	static void init() {
		jiechen[0] = 1;
		jiechenniyuan[0] = 1;
		for(int i=1;i<N;i++) {
			jiechen[i] = jiechen[i-1] * i%Mod;
			jiechenniyuan[i] = jiechenniyuan[i-1] * qpow(i, Mod-2)%Mod;
		}
	}
	//C(a,b) = a!/(b! * (a-b)!) = a! * niyuan(b!) * niyuan((a-b)!)
	static long C(int a,int b) {
		long res = 1;
		res = res * jiechen[a]%Mod;
		res = res * jiechenniyuan[b]%Mod;
		res = res * jiechenniyuan[a-b]%Mod;
		return res;
	}
https://www.acwing.com/activity/content/code/content/5904493/

扩展欧几里得算法

裴蜀定理

  • 若a,b是整数,且gcd(a,b)=d,那么对于任意的整数x,y,都有ax+by都一定是d的倍数。(充要的)
    特别地,一定存在整数x,y,使ax+by=d成立。

换句话说:

  • 两个整数a,b,方程a*x+b*y=m有解,当且仅当m是gcd(a,b)的倍数(充要)

扩展欧几里得代码:

java 复制代码
// 求x, y,使得ax + by = gcd(a, b)
// 扩展欧几里得:求解方程ax+by=gcd(a,b)的解
// x=y′ y=x′−[a/b]*y′
static int x, y;//全局变量,替代引用
int exgcd(int a,int b){
    if(b==0){
        x=1,y=0;
        return a;
    }

    int gcd=exgcd(b,a%b);//递归调用
    int tmp = x;
    x=y,y=tmp-a/b*y;
    return gcd;
}

	//结果说明
	1.exgcd()的返回值是最大公约数
 	2.最后的(x,y)是方程ax + by = gcd(a,b)的解
    3.如果exgcd()的结果是1(那么a和b互质,就存在逆元),那么x是a的逆元(x可能是负数,所以答案是getMod(x))

费马小定理

描述:

如果一个数p是质数,并且a不是p的倍数,那么有a^(p-1) = 1 (mod p)。
除以p同余

等价于:(推荐)

如果一个数p是质数,并且a和p互质(等价于gcd(a,p)=1),那么有a^(p-1) = 1 (mod p)
相关推荐
pianmian14 小时前
python数据结构基础(7)
数据结构·算法
好奇龙猫6 小时前
【学习AI-相关路程-mnist手写数字分类-win-硬件:windows-自我学习AI-实验步骤-全连接神经网络(BPnetwork)-操作流程(3) 】
人工智能·算法
sp_fyf_20247 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01
人工智能·深度学习·神经网络·算法·机器学习·语言模型·数据挖掘
香菜大丸7 小时前
链表的归并排序
数据结构·算法·链表
jrrz08287 小时前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
oliveira-time7 小时前
golang学习2
算法
南宫生8 小时前
贪心算法习题其四【力扣】【算法学习day.21】
学习·算法·leetcode·链表·贪心算法
懒惰才能让科技进步9 小时前
从零学习大模型(十二)-----基于梯度的重要性剪枝(Gradient-based Pruning)
人工智能·深度学习·学习·算法·chatgpt·transformer·剪枝
Ni-Guvara9 小时前
函数对象笔记
c++·算法
泉崎9 小时前
11.7比赛总结
数据结构·算法