蓝桥杯中常用的数学算法

Posted JunMain

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯中常用的数学算法相关的知识,希望对你有一定的参考价值。

文章目录

算数基本定义

任何一个合数都可以写成,若干个质数相乘

n = q 1 B 1 ∗ q 2 B 2 ∗ ⋅ ⋅ ⋅ ∗ q n B n n = q_1^B_1 * q_2^B_2 * ···*q_n^B_n n=q1B1q2B2qnBn (n是一个合数, q i q_i qi是质数)

因此只要是一个合数我们就可以分解质因数,并且 n最多只有一个大于 n \\sqrtn n 的质因子

分解质因数 O ( n ) O(\\sqrtn) O(n )

#include<bits/stdc++.h>
using namespace std;

int main()

	int n;
    cin >> n;
    
    for (int i = 2; i <= n / i; i ++)
    
        if (n % i == 0)
        
            int s = 0;
            while (n % i == 0)
            
                n /= i;
                s ++;
            
            cout << i << " " <<  s << endl;
        
    
    
    if (n > 1)	cout << n << " " << 1 << endl;
    
	return 0;


质数

质数是除了1和本身外不能被其他数字整除的数字


试除法 O ( n ) O(\\sqrtn) O(n )

#include<bits/stdc++.h>
using namespace std;

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;



int main()

    int n;
    cin >> n;
    
    cout << is_prime(n);    
    
    return 0;


朴素筛法求质数 ( n l o g n ) (nlog_n) (nlogn)

利用筛法可以求出1 - n中的所有素数, 可以进行预处理

基本思路:把所有数字的倍数删掉,剩下的数字就是质数

#include<bits/stdc++.h>
using namespace std;

const int N = 1000010;

bool st[N];
int prime[N], cnt;

int main()

    int n;
    cin >> n;
    
    for (int i = 2; i <= n; i ++)
    
        if (!st[i])
            prime[cnt ++] = i;
        for (int j = i; j <= n; j += i)		st[i] = true;
    
    
    return 0;



埃式筛法 O ( n l o g l o g n ) O(nlog_log_n) O(nloglogn) ~ O ( n ) O(n) O(n)

一个埃及人发明的筛法

根据算数基本定理:任何一个合数都是有若干个质数相乘,

我们可以优化上面的朴素筛法,每次去掉质数的倍数, 最后剩下的一定是素数

#include<bits/stdc++.h>
using namespace std;

const int N = 100010;

bool st[N];
int prime[N], cnt;

int main()

    int n;
    cin >> n;
   
    for (int i = 2; i <= n; i ++)
    
        if (!st[i])
        
            prime[cnt ++] = i;
            for (int j = i; j <= n; j += i)		st = true;
        
    return 0;



线性筛法 O ( n ) O(n) O(n)

线性筛法的核心原理: 一个合数n只会被它的最小质因子筛掉

#include<bits/stdc++.h>
using namespace std;

const int N = 1000010;

bool st[N];
int prime[N], cnt;


int main() 

    int n;
    cin >> n;
    
    for (int i = 2; i <= n; i ++)
    
        if (!st[i])		prime[cnt ++] = i;
        
        for (int j = 0; prime[j] <= n / i; j ++)	//从小到大枚举所有质数
        
            st[prime[j] * i] = true;			//i%p[j]!=0	 p[j]一定小于i的所有质因子一定是 p[j]*i 的最小质因子
            if (i % prime[j] == 0)	break;		//i%p[j]==0  p[j]此时一定是i的最小质因子
        
    
        
    return 0;



约数

试除法求约数 O ( n ) O(\\sqrtn) O(n )

n n n 的约数

#include<bits/stdc++.h>
using namespace std;

vector<int> res;

int main()

    int n;
    cin >> n;
    
    for (int i = 1; i <= n / i; i ++)
    
        if (n % i == 0)
        
            res.push_back(i);
            if (i != n / i )	res.push_back(n / i);	//特判 平方
        
    
    
    sort(res.begin(), res.end());
    
    
    return 0;



求约数个数 O ( n ) O(\\sqrtn) O(n )

算数基本定理: n = q 1 B 1 ∗ q 2 B 2 ∗ ⋅ ⋅ ⋅ ∗ q n B n n = q_1^B_1 * q_2^B_2 * ···*q_n^B_n n=q1B1q2B2qnBn (n是一个合数, q i q_i qi是质数)

公式: n的约数个数 = ( B 1 + 1 ) ∗ ( B 2 + 1 ) ∗ ⋅ ⋅ ⋅ ∗ ( B n + 1 ) (B_1 + 1)*(B_2 + 1)*···*(B_n + 1) (B1+1)(B2+1)(Bn+1)

int 范围内约数的个数最多在1500个左右

#include<bits/stdc++.h>
using namespace std;

unordered_map<int,int> mp;

int ans = 1;

int main()

    int n; 
    cin >> n;
    
    for (int i = 2; i <= n / i; i ++)
    
        if (n % i == 0)
        
            while (n % i == 0)
            
                mp[i] ++;
                n /= i;
            
        
    
    
    if (n > 1)	mp[n] ++;
    
    for (auto m : mp)
        ans *= (m.second + 1);
    
    
    cout << ans;
    
    return 0;




求约数之和

算数基本定理: n = q 1 B 1 ∗ q 2 B 2 ∗ ⋅ ⋅ ⋅ ∗ q n B n n = q_1^B_1 * q_2^B_2 * ···*q_n^B_n n=q1B1q2B2qnB尽快收藏蓝桥杯常用算法模板

Codeforces 577B Modulo Sum:数学 结论选数之和为m的倍数

蓝桥杯 算法训练 ALGO-146 4-2找公倍数

蓝桥杯国奖学长带你复盘第十三届蓝桥杯模拟赛

蓝桥杯练习系统—算法训练 最小最大公倍数

1356. 回文质数难度: 中 / 数学