数学知识(二)

一、裴蜀定理

对于任意整数a,b,一定存在非零整数x,y,使得 ax + by = gcd(a,b)

cpp 复制代码
#include<iostream>
#include<algorithm>

using namespace std;

int exgcd(int a,int b,int &x,int &y)
{
    if(!b)
    {
        x = 1,y = 0;
        return a;
    }
    
    int d = exgcd(b,a % b,y,x);
    
    y -= a / b * x;
    
    return d;
}

int main()
{
    int n;
    scanf("%d",&n);
    
    while(n --)
    {
        int a,b,x,y;
        scanf("%d%d",&a,&b);
        
        exgcd (a,b,x,y);
        
        printf("%d%d\n",x,y);
    }
    return 0;
}

二、高斯消元

步骤:枚举每一列,取列c

  • 1、找到绝对值最大的一行
  • 2、将该行换到最上面
  • 3、将该行第一个数变为1(与该行其它数的比值不改变)
  • 4、将下面所有行的第c列消为零
cpp 复制代码
#include<iostream>
#include<cmath>
#include<algorithm>

using namespace std;

const int N = 110;
const double eps = 1e-6;

int n;
double a[N][N];

int gauss()
{
    int c,r;
    for(c = 0,r = 0; c < n;c ++)
    {
        //找到绝对值最大的一行
        int t = r;
        for(int i = r; i < n; i ++)
            if(fabs(a[i][c]) > fabs(a[t][c])) t = i;

        if(fabs(a[t][c]) < eps) continue;

        //将该行换到最上方
        for(int i = c;i <= n;i ++) swap(a[t][i],a[r][i]);
        //将该行第一个数变为1
        for(int i = n;i >= c; i --) a[r][i] /= a[r][c];
        //将下面所有行消为0
        for(int i = r + 1;i < n;i ++)
            if(fabs(a[i][c]) > eps)
               for(int j = n;j >= c;j --)
                    a[i][j] -= a[r][j] * a[i][c];

        r ++;
    }
    if(r < n)
    {
        for(int i = r;i < n;i ++)
            if(fabs(a[i][n]) > eps)
               return 2; //无解

        return 1; //有无穷多组解
    }
    
    for(int i = n - 1;i >= 0;i --)
        for(int j = i + 1;j < n;j ++)
           a[i][n] -= a[i][j] * a[j][n];
    
    return 0; //存在唯一的解
}

三、求组合数

cpp 复制代码
#include<iostream>
#include<cmath>
#include<algorithm>

using namespace std;

const int N = 2010,mod = 1e9 + 7;
int c[N][N];

//初始化
void init()
{
    for(int i = 0;i < N;i ++)
        for(int j = 0;j <= i;j ++){
            if(!j) c[i][j] = 1;
            else c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
        }

}
int main()
{
    init();

    int n;
    scanf("%d",&n);

    while(n --)
    {
        int a,b;
        scanf("%d%d",&a,&b);

        printf("%d\n",c[a][b]);
    }
    return 0;
}

第二种方法:

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<cmath>

using namespace std;

typedef long long LL;
const int N = 100010,mod = 1e9 + 7;

int fact[N],infact[N];

int qmi(int a,int k,int p)
{
    int res = 1;
    while(k)
    {
        if(k & 1) res = (LL) res *a % p;
        a = (LL)a * a % p;
        k >>= 1;
    }
    return res;
}

int main()
{
    fact[0] = infact[0] = 1;
    for(int i = 1;i < N;i ++)
    {
        fact[i] = (LL)fact[i - 1] * i % mod;
        infact[i] = (LL)infact[i - 1] * qmi(i,mod - 2,mod) % mod;
    }

    int n;
    scanf("%d",&n);

    while(n --)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        printf("%d\n",(LL)fact[a] * infact[b] % mod * infact[a - b] % mod);
    }
    return 0;
}
相关推荐
52Hz1181 小时前
力扣24.两两交换链表中的节点、25.K个一组反转链表
算法·leetcode·链表
老鼠只爱大米1 小时前
LeetCode经典算法面试题 #160:相交链表(双指针法、长度差法等多种方法详细解析)
算法·leetcode·链表·双指针·相交链表·长度差法
ValhallaCoder1 小时前
Day53-图论
数据结构·python·算法·图论
老鼠只爱大米1 小时前
LeetCode经典算法面试题 #84:柱状图中最大的矩形(单调栈、分治法等四种方法详细解析)
算法·leetcode·动态规划·单调栈·分治法·柱状图最大矩形
C雨后彩虹1 小时前
羊、狼、农夫过河
java·数据结构·算法·华为·面试
重生之后端学习2 小时前
19. 删除链表的倒数第 N 个结点
java·数据结构·算法·leetcode·职场和发展
aini_lovee2 小时前
严格耦合波(RCWA)方法计算麦克斯韦方程数值解的MATLAB实现
数据结构·算法·matlab
安特尼2 小时前
推荐算法手撕集合(持续更新)
人工智能·算法·机器学习·推荐算法
鹿角片ljp2 小时前
力扣14.最长公共前缀-纵向扫描法
java·算法·leetcode
Remember_9932 小时前
【数据结构】深入理解优先级队列与堆:从原理到应用
java·数据结构·算法·spring·leetcode·maven·哈希算法