首页 > 其他分享 >数学

数学

时间:2024-08-23 21:27:11浏览次数:6  
标签:return int sum 数学 choose ans binom

数学

数论

唯一分解定理

定理

对于任意正整数 \(a\),均有:

\[a=p_1^{k_1}p_2^{k_2}\cdots p_n^{k_n} \]

其中 \(p_1,p_2\cdots p_n\)均为质数。

约数和公式

对于任意正整数 \(a=p_1^{k_1}p_2^{k_2}\cdots p_n^{k_n}\),其约数和 \(k\) 为

\[k=({p_1}^0+{p_1}^1+ \cdots {p_1}^{k_1})({p_2}^0+{p_2}^1+\cdots+{p_2}^{k_2})\cdots({p_n}^0+{p_n}^1+\cdots+{p_n}^{k_n}) \]

裴蜀定理

采用常用的形式描述:

对于方程 \(ax+by=c\),当且仅当 \(\gcd(a,b)\mid c\) 时,方程有整数解。

扩展欧几里德算法

  1. 解方程 \(ax+by=gcd(a,b)\)

运用以下代码求出一个特解 \(x_0\).

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

则方程最小正整数解 \(x=(x_0\%b+b)\%b\)。

  1. 解方程 \(ax+by=c\)

记 \(g=gcd(a,b)\),则:

a. 若 \(g\nmid c\),原方程无整数解。

b. 若 \(g\nmid c\),先转化为问题1,求方程 \(ax+by=gcd(a,b)\) 的一个特解 \(x_0\),记 \(k=\frac{b}{g}\) ,那么原方程的一个特解 \(x_1\) 就是 \(x_1=k\times x_0\).

方程的最小正整数解就是 \(x=(x_1\%k+k)\%k\).

逆元

求 \(a^{-1}\pmod p\)

费马小定理求逆元

当 \(p\) 为质数时,我们可以用费马小定理求 \(a^{-1}=a^{p-2}\).

代码:

int qpow(int x, int y) {
    int ans = 1;
    while (y) {
        if (y & 1)
            ans = ans * x % p;
        x = x * x % p;
        y >>= 1;
    }
    return ans;
}

扩展欧几里德定理求逆元

当 \(\gcd(a,b)=1\)时,我们可以通过调用 \(exgcd(a,p,x,y)\) 求出 \(a^{-1}=x\)。

代码:

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

线性递推求逆元

当需要线性递推求逆元时,采用以下代码求逆元。

inv[1] = 1;
for (int i = 2; i <= n; ++i) {
  inv[i] = (long long)(p - p / i) * inv[p % i] % p;
}

线性同余方程

形如 $ ax\equiv b\pmod n $ 的方程称为线性同余方程

方程的解是 $ x\equiv ba ^ {- 1} \pmod n.$

欧拉函数

\(\varphi(i)\) 表示的是小于等于 \(n\) 和 \(n\) 互质的数的个数。

求单个数欧拉函数的求法:

int solve(int n) {
	int 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;
}

筛法求欧拉函数:

vector<int>v;
int phi[N];
bitset<N>pri;
int n;
void get_p() {
	phi[1] = 1;
	for (int i = 2; i <= n; i++) {
		if(!pri[i]) {
			v.push_back(i);
			phi[i] = i - 1;
		}
		for(int j = 0; j < (int)v.size() && v[j] * i <= n; j++) {
			pri[i * v[j]] = true;
			if(i % v[j] == 0) {
				phi[i * v[j]] = phi[i] * v[j];
				break;
			}
			phi[i * v[j]] = phi[i] * phi[v[j]];
		}
	}
}

欧拉定理

欧拉定理

若 \(gcd(a, m) = 1\) ,则 \(a^{\varphi(m)} \equiv 1 \pmod{m}\)

扩展欧拉定理

$ a^b\equiv \begin{cases} a^{b\bmod\varphi(p)},,&\gcd(a,,p)=1\ a^b,&\gcd(a,,p)\ne1,,b<\varphi(p)\ a^{b\bmod\varphi(p)+\varphi(p)},&\gcd(a,,p)\ne1,,b\ge\varphi(p) \end{cases} \pmod p $

中国剩余定理

中国剩余定理

中国剩余定可求解如下形式的一元线性同余方程组(其中 \(n_1, n_2, \cdots, n_k\) 两两互质)

\[\begin{cases} x &\equiv a_1 \pmod {n_1} \\ x &\equiv a_2 \pmod {n_2} \\ &\vdots \\ x &\equiv a_k \pmod {n_k} \\ \end{cases} \]

具体解法:

  1. 计算所有模数的积 \(n\)

  2. 对于第 \(i\) 个方程:

    a. 计算 \(m_i=\frac{n}{n_i}\)

    b.计算 \(m_i\) 在模 \(n_i\) 意义下的逆元 \(m^{-1}\)

    c.计算 \(c_i=m_im_i^{-1}\)(不要对 \(n_i\) 取模)

  3. 方程组在模 \(n\) 意义下的唯一解为 \(x=\sum^k_{i=1}a_ic_i \pmod n\)

实现:

int CRT(int m[], int r[]) {
	int M = 1, ans = 0;
	for(int i = 1; i <= n; i++) 
		M *= m[i];
	for(int i = 1; i <= n; i++) {
		int c = M / m[i], x, y;
		exgcd(c, m[i], x, y);
		ans = (ans + r[i] * c * x % M + M) % M;
	}
	return (ans + M) % M;
}

扩展中国剩余定理

当方程组中每一个模数 \(n_i\) 不互质时,需要用到中国剩余定理。

考虑两个方程的情况。

设两个方程分别是 \(x\equiv a_1 \pmod {m_1}\),\(x\equiv a_2 \pmod {m_2}\)

将它们转化为不定方程: \(x=m_1p+a_1=m_2q+a_2\) ,其中 \(p, q\) 是整数,则有 \(m_1p-m_2q=a_2-a_1\) 。

由 裴蜀定理,当 \(a_2-a_1\) 不能被 \(\gcd(m_1,m_2)\) 整除时,无解

其他情况下,可以通过 扩展欧几里得算法 解出来一组可行解 \((p, q)\) ;

则原来的两方程组成的模方程组的解为 \(x\equiv b\pmod M\) ,其中 \(b=m_1p+a_1\) , \(M=\text{lcm}(m_1, m_2)\) 。

然后多个方程时两两合并即可。

代码:

int md[N], rem[N];//存模数和余数
int qmul(int a, int b, int p) {//龟速乘
	int ans = 0;
	while (b) {
		if (b & 1)
			ans = (ans + a) % p;
		a = (a + a) % p;
		b >>= 1;
	}
	return ans;
}
int exgcd(int a, int b, int &x, int &y) {
	if (b == 0) {
		x = 1;
		y = 0;
		return a;
	}
	int gcd = exgcd(b, a % b, x, y);
	int t = x;
	x = y;
	y = t - a / b * y;
	return gcd;
}
signed main() {
	ios::sync_with_stdio(0);
	cin >> n;
	for (int i = 1; i <= n; i++)
		cin >> md[i] >> rem[i];
	int X = rem[1];//存解
	int LCM = md[1];//存前 i - 1 个方程模数的lcm
	for(int i = 2; i <= n; i++) {
		int p = md[i];
		int res = ((rem[i] - X) % p + p) % p;
		int x, y, Gcd = exgcd(LCM, p, x, y);
		if(res % Gcd) {//判断无解
			puts("-1");
			return 0;
		}
		x = qmul(x, res / Gcd, p);
		X += x * LCM;
		LCM = p / Gcd * LCM;
		X = (X % LCM + LCM) % LCM;
	}
	cout << X << "\n";
	return 0;
}

排列组合

排列组合三大方法

插板法

不允许为空的插板

有 \(n\) 个元素,分为 \(k\) 组,每组保证有一个元素,问方案数。
公式:

\[{n-1\choose k-1} \]

允许为空的插板

有 \(n\) 个元素,分为 \(k\) 组,每组允许为空,问方案数。
公式:

\[{n+k-1\choose n} \]

插空法

若有 \(n\) 个 \(A\) 类物品和 \(m\) 个 \(B\) 类物品,将其插入一段长度为 \(n+m\) 的序列,且要求 \(B\) 类物品不能相邻,求方案数。

公式:

\[A^n_n\times A^m_{n+1} \]

先计算 \(A\) 类物品的排列情况:\(A_n^n\),此时我们认为序列里共有 \(n+1\) 个空,此时 \(B\) 类物品的情况就是 \(A_{n+1}^m\) 了。最终答案就是二者相乘。

捆绑法

若有 \(n\) 个 \(A\) 类物品和 \(m\) 个 \(B\) 类物品,将其插入一段长度为 \(n+m\) 的序列,且要求 \(B\) 类物品必须相邻,求方案数。

公式:

\[A_{n+1}^{n+1}\times A^m_m \]

将所有 \(B\) 类物品看为一个物品,此时的排列情况是 \(A_{n+1}^{n+1}\),再考虑 \(B\) 类物品内部的情况,方案数是 \(A_{m}^{m}\),最终答案就是二者相乘。

二项式定理

\[(a+b)^n=\sum^n_{i=0} {n\choose i} a^{n-i}b^i \]

二项式反演

形式1

记 \(f_n\) 为恰好使用 \(n\) 个不同元素形成特定结构的方案数, \(g_n\) 为从 \(n\) 个不同元素中选出 \(i\geq 0\) 个元素形成特定结构的方案数。

若已知 \(f_n\) 求 \(g_n\),则显然:

\[g_n=\sum^n_{i=0}{n\choose i}f_i \]

若已知 \(g_n\) 求 \(f_n\),则有:

\[f_n=\sum^n_{i=0}{n\choose i}(-1)^{n-i}g_i \]

形式2

记 \(f_k\) 为恰好使用 \(k\) 个不同元素形成特定结构的方案数, \(g_k\) 为从 \(n\) 个不同元素中选出 \(i\geq k\) 个元素形成特定结构的方案数。

若已知 \(f_k\) 求 \(g_k\),则显然:

\[g_k=\sum^n_{i=k}{i\choose k}f_i \]

若已知 \(g_k\) 求 \(f_k\),则有:

\[f_k=\sum^n_{i=k}{i\choose k}(-1)^{n-k}g_k \]

或许可以把它理解成一种容斥的变形?

二项式反演的主要用途是在把所求答案是恰好,但至少/不多于这样的答案好求时可以转化答案进行计算。

卢卡斯定理

若 \(p\) 为质数,对于 \(n,m\) 很大, \(p\) 很小时的公式:

\[{n\choose m}={{\lfloor n/p \rfloor }\choose {\lfloor m/p \rfloor}}\cdot{{n\mod p}\choose{m\mod p}} \]

代码:

int C(int n, int m) {
	if(m > n)
		return 0;
	return fac[n] * qpow(fac[m] * fac[n - m] % p, p - 2) % p;
}
int Lucas(int n, int m) {
	if(m > n)
		return 0;
	if(!m)
		return 1;
	return C(n % p, m % p) * Lucas(n / p, m / p) % p;
}

错排问题

错位排列是没有任何元素出现在其有序位置的排列。即,对于 \(1\sim n\) 的排列 \(P\) ,如果满足 \(P_i\neq i\) ,则称 \(P\) 是 \(n\) 的错位排列。

递推公式:

\(D_1=0,\ D_2=1,\ D_3=2;\)

\(D_n=(n-1)(D_{n-1}+D_{n-2})\)

常用公式

\[ \binom{n}{m}=\binom{n}{n-m} \]

\[\binom{n}{k} = \frac{n}{k} \binom{n-1}{k-1} \]

\[ \binom{n}{m}=\binom{n-1}{m}+\binom{n-1}{m-1} \]

\[\binom{n}{0}+\binom{n}{1}+\cdots+\binom{n}{n}=\sum_{i=0}^n\binom{n}{i}=2^n \]

\[ \sum_{i=0}^n(-1)^i\binom{n}{i}=[n=0] \]

\[ \sum_{i=0}^m \binom{n}{i}\binom{m}{m-i} = \binom{m+n}{m}\ \ \ (n \geq m) \]

\[\sum_{i=0}^ni\binom{n}{i}=n2^{n-1} \]

\[ \sum_{i=0}^ni^2\binom{n}{i}=n(n+1)2^{n-2} \]

\[\sum_{i=0}^n{l\choose k}={{n+1}\choose k+1} \]

\[\binom{n}{r}\binom{r}{k} = \binom{n}{k}\binom{n-k}{r-k} \]

\[ \sum_{i=0}^n\binom{n-i}{i}=F_{n+1} \]

其中 \(F\) 是斐波那契数列。

\[ \sum_{i=0}^ni^2\binom{n}{i}=n(n+1)2^{n-2} \]

数学方法

高斯消元

一般使用高斯-约旦消元法

// Gauss_Jordan 模板
#include <bits/stdc++.h>
#define N 105
using namespace std;
const double eps = 1e-6;
int n;
double a[N][N];
bool gauss_jordan() {
    for (int i = 1; i <= n; i++) {
        int r = i;
        for (int k = i; k <= n; k++)
            if (fabs(a[k][i]) > eps) {
                r = k;
                break;
            }
        if (r != i)
            swap(a[r], a[i]);
        if (fabs(a[i][i]) < eps)
            return false;
        for (int k = 1; k <= n; k++) {
            if (k == i)
                continue;
            double t = a[k][i] / a[i][i];
            for (int j = i; j <= n + 1; j++)
                a[k][j] -= t * a[i][j];
        }
    }
    for (int i = 1; i <= n; i++)
        a[i][n + 1] /= a[i][i];
    return true;
}
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n + 1; j++)
            scanf("%lf", &a[i][j]);
    if (gauss_jordan())
        for (int i = 1; i <= n; i++)
            printf("%.2lf\n", a[i][n + 1]);
    else
        puts("No Solution");
    return 0;
}

BSGS

给定一个质数 \(p\),以及一个整数 \(a\),一个整数 \(b\),现在要求你计算一个最小的非负整数 \(l\),满足 \(a^l \equiv b \pmod p\)。

#include <bits/stdc++.h>
#define int long long
using namespace std;
int p, a, b;
int BSGS() {
	unordered_map<int, int>mp;
	a %= p;
	b %= p;
	int s = ceil(sqrt(p));
	int t = b;
	mp[b] = 0;
	for (int i = 1; i <= s; i++) {
		t = t * a % p;
		mp[t] = i; 
	}
	int x = 1;
	for (int i = 1; i <= s; i++)
		x = x * a % p;
	t = 1;
	for (int i = 1; i <= s; i++) {
		t = t * x % p;
		if (mp.count(t))
			return i * s - mp[t];
	}
	return -1;
}
signed main() {
	cin >> p >> a >> b;
	int tmp = BSGS();
	if(~tmp)
		cout << tmp << "\n";
	else
		puts("no solution");
	return 0;
}

标签:return,int,sum,数学,choose,ans,binom
From: https://www.cnblogs.com/Rock-N-Roll/p/18377117

相关文章

  • Scratch编程乐园:探索数学函数的无限可能
    标题:Scratch编程乐园:探索数学函数的无限可能在少儿编程教育领域,Scratch以其独特的视觉化编程方式,激发了无数孩子的编程兴趣。它不仅仅是一个编程工具,更是一个创意表达的平台。然而,对于有志于深入探索数学世界的孩子们来说,Scratch是否提供了数学函数库,如三角函数或统计函数?......
  • 创建菱形图案时的数学思维
    目录前言附:样例1.1固定生成5*5大小的菱形(最简单最基本的图形生成)2.1生成n*n大小的菱形(本质上缩小或增大了基本图形)3.1生成n*m大小的菱形(本质上在第二种变化基础上增加了角度变化)一.固定生成5*5基本大小的菱形(后文中称其为基础菱形)1. 分析原理1.1 代码逻辑1.2数......
  • 组合数学总结
    数学是毒瘤组合数学总结。如果说数论是数学的基础,那么组合数学往后就是高阶了。这之后的数学不再像数论那么板子,而是变得需要更多的推理和组合了。知识很简单,难的是应用。本来还有什么容斥原理,看不懂,于是没放初始化为了方便快速求排列组合,我们需提前预处理阶乘和阶乘的乘法......
  • 组合数学
    梦回选修\(2\)QAQ。这东西说实话的确考察思维,而且容易和dp什么的综合起来难度就直接飙到\(*3000\),但是组合数学的确是一个极其重要的部分,它可以在很多情况下帮你减少枚举次数(比如去年T2的哈希做法如果最后直接组合数学统计答案的话码量少了整整\(30\)行!),所以这也是以后的......
  • 斯特林数学习笔记
    定义第二类斯特林数\(n\bracem\)表示\(n\)个两两不同的元素划分为\(m\)个互不区分的非空子集的方案数;第一类斯特林数\(n\brackm\)表示\(n\)个两两不同的元素划分为\(m\)个互不区分的非空轮换(可以理解为环)的方案数。第二类斯特林数的递推式:\({n\bracem}={n-1\bra......
  • 高中数学知识点(一)
    文章目录一、集合1.集合和元素的概念2.集合间的关系3.集合间的运算二、函数1.区间和无穷大2.函数三要素3.具体函数和抽象函数4.判断同一函数5.求函数值6.换元法求函数解析式7.映射8.函数的表示方法9.分段函数10.抽象函数图像的平移11.函数的周期性二、......
  • F. Expected Median(组合数学,模板)
    题目来源:https://codeforces.com/contest/1999/problem/F//题意:给长度为n的01字符串,求每个长度为k的子序列串(不连续)的中位数总和。//思路:n的范围为2e5,“我也不会非暴力求所有子序列啊”。先理解下什么是中位数吧,就是对于有序的中间数字,奇数就是(k+1)/2。也只有中位数是1的子序列......
  • 高等数学学习笔记(二)
    高等数学学习笔记(二)书接上回。我们已经了解熟悉了数列极限的相关知识。本篇我们从函数极限开始。Chapter4函数的极限1.自变量趋于无穷大时函数的极限对于定义在实数集上的函数\(f(x)\),自变量\(x\)趋于无穷大有三种形式①\(x\to+\infty\),即沿\(x\)轴正向趋于无穷大(......
  • 考研数学针对性训练,按章节刷题
    前言考研数学目前大家都在如火如荼地进行强化,有一些同学已经遇到了一些问题,某个章节学不会,想专项复习一下,但是又不知道怎么搞,之前也有很多小伙伴问我如何按章节刷题,那么在此给大家解答一下。方法一在考研数学欧几里得里的刷题模块,可以按章节刷题,各个大章以及小节都可以选择......
  • 数学教材推荐
    作者:Duality链接:https://www.zhihu.com/question/447079814/answer/1783883000来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。大三了,教材选择上走了不少弯路,说一下自己的经验。babyrudin这书没必要看,上来讲一堆点集拓扑降低了理解的难度,缺少数......