【备战蓝桥杯】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)
相关推荐
马剑威(威哥爱编程)1 小时前
除了递归算法,要如何优化实现文件搜索功能
java·开发语言·算法·递归算法·威哥爱编程·memoization
算法萌新——12 小时前
洛谷P2240——贪心算法
算法·贪心算法
湖北二师的咸鱼2 小时前
专题:二叉树递归遍历
算法·深度优先
重生之我要进大厂2 小时前
LeetCode 876
java·开发语言·数据结构·算法·leetcode
KBDYD10103 小时前
C语言--结构体变量和数组的定义、初始化、赋值
c语言·开发语言·数据结构·算法
Crossoads3 小时前
【数据结构】排序算法---桶排序
c语言·开发语言·数据结构·算法·排序算法
自身就是太阳3 小时前
2024蓝桥杯省B好题分析
算法·职场和发展·蓝桥杯
孙小二写代码3 小时前
[leetcode刷题]面试经典150题之1合并两个有序数组(简单)
算法·leetcode·面试
little redcap4 小时前
第十九次CCF计算机软件能力认证-1246(过64%的代码-个人题解)
算法
David猪大卫4 小时前
数据结构修炼——顺序表和链表的区别与联系
c语言·数据结构·学习·算法·leetcode·链表·蓝桥杯