• 数论小结


    记录蓝桥杯中常用的数论模板

    1-1欧几里得算法gcd

    typedef long long ll;
    ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
    

    1-2 最小公倍数

    int icm(ll a, ll b) { return a * b / gcd(a, b); }
    

    1-3 扩展欧几里得exgcd

    exgcd求解线性方程组模板

    int x, y;
    
    //扩展欧几里得
    int exgcd(int a, int b) {
        if (b == 0) {
            x = 1, y = 0;
            return a;
        }
        int res = exgcd(b, a % b);
        int x1 = x;
        x = y, y = x1 - a / b * y;
        return res;
    }
    
    //求解线性方程 解为x和y
    int line(int a, int b, int m) {
        int d = exgcd(a, b);
        if (m % d != 0) return -1;
        int n = m / d;
        x *= n, y *= n;
        return d;
    }
    

    exgcd一道例题蓝桥杯决赛:一步之遥

    从昏迷中醒来,小明发现自己被关在X星球的废矿车里。
    矿车停在平直的废弃的轨道上。
    他的面前是两个按钮,分别写着“F”和“B”。
    
    小明突然记起来,这两个按钮可以控制矿车在轨道上前进和后退。
    按F,会前进97米。按B会后退127米。
    透过昏暗的灯光,小明看到自己前方1米远正好有个监控探头。
    他必须设法使得矿车正好停在摄像头的下方,才有机会争取同伴的援助。
    或许,通过多次操作F和B可以办到。
    
    矿车上的动力已经不太足,黄色的警示灯在默默闪烁...
    每次进行 F 或 B 操作都会消耗一定的能量。
    小明飞快地计算,至少要多少次操作,才能把矿车准确地停在前方1米远的地方。
    
    请填写为了达成目标,最少需要操作的次数。
    
    注意,需要提交的是一个整数,不要填写任何无关内容(比如:解释说明等)
    
    

    使用exgcd的做法,因为97,127互质。两组特解之和即为答案

    #include <bits/stdc++.h>
    using namespace std;
    int x, y;
    int exgcd(int a, int b) {
        if (b == 0) {
            x = 1, y = 0;
            return a;
        }
        int res = exgcd(b, a % b);
        int x1 = x;
        x = y, y = x1 - a / b * y;
        return res;
    }
    int line(int a, int b, int m) {
        int d = exgcd(a, b);
        if (m % d != 0) return -1;
        int n = m / d;
        x *= n, y *= n;
        return d;
    }
    
    int main() {
        int d, a = 97, b = -127;
        d = line(97, -127, 1);
        cout << d << endl;  //求解方程2x + 7y = 1的 未知数x和未知数y的一个解
        cout << x << " " << y << endl;
        cout << abs(x) + abs(y) << endl;
        b = 127 / d;  //求解第一个大于0的解 先把b对gcd(a,b)化简
                      // cout<<"第一个大于0的解x:"<<(x%b+b)%b<<endl;
    }
    

    2-3:线性方程什么时候有解,什么时候无解,无解的最大值是多少

    蓝桥杯往届例题:2014年A组-买不到的数目 (求系数为正整数时方程,无解时的最大上界:数学规律a*b-a-b)
    蓝桥杯往届例题:2017年AB组-包子凑数(问什么时候无解,当a1,a2,a3....an互质时无解)

    3:同余方程

    3-1exgcd解同余方程

    将同余方程转换为 线性方程,当且仅当b是gcd(a,n)的倍数,n是余数

    3-2:一道例题:poj1061青蛙的约会

    写出同余方程,转成线性方程,使用exgcd求解,求大于0的第一个解的公式:b = b/d,x = (x%b+b)%b;

    4-1:费马小定理

    5-1:欧拉函数

    //欧拉函数:求出小于等于n的  与n互质的个数,如果求多个数的欧拉值则要 筛法欧拉函数
    using ll = long long;
    ll Euler(ll n) {
        ll ans = n;
        for (int i = 2; i * i <= n; ++i) {
            if (n % i == 0) {
                ans = ans / i * (i - 1);
                while (n % i == 0) n /= i;
            }
        }
        if (n > 1) ans = ans / n * (n - 1);
        return ans;
    }
    

    6-1:快速幂

    using ll = long long;
    ll qpow(ll a, ll b, ll mod) {
        ll ans = 1;
        a %= mod;
        for (; b; a = a * a % mod, b >>= 1)
            if (b & 1) ans = ans * a % mod;
        return ans;
    }
    

    6-2:快速乘

    using ll = long long;
    ll qmul(ll a, ll b, ll mod) {
        ll ans = 0;
        for (; b; a = (a + a) % mod, b >>= 1)
            if (b & 1) ans = (ans + a) % mod;
        return ans;
    }
    

    7-1:素数筛

    vector<bool> prime;
    void Prime(int n) {
        prime.resize(n + 10, true);
        for (int i = 2; i * i <= n; ++i) {
            if (prime[i])
                for (int j = i * i; j <= n; j += i) prime[j] = false;
        }
    }
    

    8-1:日期计算-基姆拉尔森

    // 根据日期判断星期几
    int Day(int y, int m, int d) {
        if (m == 1 || m == 2) m += 12, y -= 1;
        return (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400 + 1) %
               7;
    }
    

    9-1:康托展开 & 逆康托展开

    【原理】

    [X = A[0] * (n-1)! + A[1] * (n-2)! + … + A[n-1] * 0!\ (A[i]表示在位置i后比位置i上数小的数的个数) ]

    【举例】

    [在 (1, 2, 3, 4, 5) 5个数的排列组合中,计算 (3, 4, 1, 5, 2) 的康托展开值\ X = 2 * 4! + 2 * 3! + 0 * 2! + 1 * 1! + 0 * 0! = 61 ]

    const int FAC[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800};
    
    int cantor(int *a) { //算出全排列对应的哈希值
        int x = 0;
        for (int i = 0; i < 9; i++) {
            int smaller = 0;
            for (int j = i + 1; j < 9; j++) {
                if (a[j] < a[i]) smaller++;
            }
            x += FAC[9 - i - 1] * smaller;
        }
        return x + 1;
        //注意全排列数组a是从零开始的
    }
    
    void decantor(int x, int *ans) { //x哈希值,n数字个数,a算出的全排列
        x--;
        vector<int> v;
        for (int i = 1; i <= 9; i++) v.push_back(i);
        for (int i = 0; i < 9; i++) {
            int r;
            r = x / FAC[9 - i - 1];
            x = x % FAC[9 - i - 1];
            sort(v.begin(), v.end());
            ans[i] = v[r];
            v.erase(v.begin() + r);
        }
        //注意算出的全排列数组ans是从0开始的
    }
    

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    (一)SAPI简述
    一、初识T4引擎
    (二)语音合成测试案例
    (三)语音合成器实例
    四、分离T4引擎
    二、T4模板
    三、T4模板与实体生成
    禁用浏览器缓存
    js_function
    asp.net(C#)读取文件夹和子文件夹下所有文件,绑定到GRIDVIEW并排序 .
  • 原文地址:https://www.cnblogs.com/RioTian/p/13794982.html
Copyright © 2020-2023  润新知