acw数学知识(下)

数论基础知识

10. 高斯消元

10.1 步骤

枚举每一列c
1.找到该列绝对值最大的一行
2.换到最上面
3.将该行第一个数变成1
4.将下面所有行的第c列消成0

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]);
		for(int i=n;i>=c;i--) a[r][i]/=a[r][c];
		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;//一组解
}

11. 组合数

11.1 递归法

1 < = b < = a < = 2000 1<=b<=a<=2000 1<=b<=a<=2000

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-1]+c[i-1][j];
11.2 通过预处理逆元的方式

1 < = b < = a < = 1 e 5 1<=b<=a<=1e5 1<=b<=a<=1e5
∵ \because a ! b ! \frac{a!}{b!} b!a! ( m o d   p ) (mod\ p) (mod p) ≠ ≠ = a !   ( m o d   p ) b !   ( m o d   p ) \frac{a!\ (mod\ p)}{b!\ (mod\ p)} b! (mod p)a! (mod p)
所以,可以转化为: a ! ∗ d ! a!*d! a!d! ( m o d   p ) (mod\ p) (mod p)
其中, d i d_i di b i b_i bi p p p 的逆元,等于 b i p − 2 b_i^{p-2} bip2

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;
}
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;//逆元
}
11.3 卢卡斯定理

1 < = b < = a < = 1 e 18 , 1 < = p < = 1 e 5 1<=b<=a<=1e18,1<=p<=1e5 1<=b<=a<=1e18,1<=p<=1e5

11.3.1定理

P P P为素数, a , b ∈   N ∗ a,b\in\ N^* a,b N,并且
a = a k ∗ p k + a k − 1 ∗ p k − 1 + ⋅ ⋅ ⋅ + a 1 ∗ p + a 0 b = b k ∗ p k + b k − 1 ∗ p k − 1 + ⋅ ⋅ ⋅ + b 1 ∗ p + b 0 a=a_k*p^k+a_{k-1}*p^{k-1}+···+a_1*p+a_0\\b=b_k*p^k+b_{k-1}*p^{k-1}+···+b_1*p+b_0 a=akpk+ak1pk1+⋅⋅⋅+a1p+a0b=bkpk+bk1pk1+⋅⋅⋅+b1p+b0
这里 0 < = a i , b i < = p − 1 0<=a_i,b_i<=p-1 0<=ai,bi<=p1都是整数, i = 0 , 1 , 2 , ⋅ ⋅ ⋅ , k i=0,1,2,···,k i=0,1,2,⋅⋅⋅,k,则有
C a b ≡ C a k b k ∗ C a k − 1 b k − 1 ∗ ⋅ ⋅ ⋅ ∗ C a 0 b 0   ( m o d   P ) C_a^b≡C_{a_k}^{b_k}*C_{a_{k-1}}^{b_{k-1} }*···*C_{a_0}^{b_0}\ (mod\ P) CabCakbkCak1bk1⋅⋅⋅Ca0b0 (mod P)

11.3.2证明

( 1 + x ) p = C p 0 ∗ 1 + C p 1 ∗ x + C p 2 ∗ x 2 + ⋅ ⋅ ⋅ + C p p ∗ x p (1+x)^p=C_p^0*1+C_p^1*x+C_p^2*x^2+···+C_p^p*x^p (1+x)p=Cp01+Cp1x+Cp2x2+⋅⋅⋅+Cppxp
因为 p p p是素数
所以 C p i ∗ x i C_p^i*x_i Cpixi没有 < p <p <p的质因子,可知 C p i ∗ x i ≡ 0   ( m o d   p ) C_p^i*x_i\equiv0\ (mod\ p) Cpixi0 (mod p)
得到 ( 1 + x ) p ≡ 1 + x p   ( m o d   p ) (1+x)^p≡1+x^p\ (mod\ p) (1+x)p1+xp (mod p)
利用上述结果,可知
( 1 + x ) a = ( 1 + x ) a 0 ∗ ( ( 1 + x ) p ) a 1 ∗ ⋅ ⋅ ⋅ ∗ ( ( 1 + x ) p k ) a k                             ≡ ( 1 + x ) a 0 ∗ ( ( 1 + x p ) a 1 ∗ ⋅ ⋅ ⋅ ∗ ( ( 1 + x p k ) a k   ( m o d   p ) (1+x)^a=(1+x)^{a_0}*((1+x)^p)^{a_1}*···*((1+x)^{p_k})^{a_k}\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \equiv(1+x)^{a_0}*((1+x^p)^{a_1}*···*((1+x^{p_k})^{a_k}\ (mod\ p) (1+x)a=(1+x)a0((1+x)p)a1⋅⋅⋅((1+x)pk)ak                           (1+x)a0((1+xp)a1⋅⋅⋅((1+xpk)ak (mod p)
左右式中, x b x^b xb的系数相等可得
C a b ≡ C a k b k ∗ C a k − 1 b k − 1 ∗ ⋅ ⋅ ⋅ ∗ C a 0 b 0   ( m o d   p ) C_a^b\equiv C_{a_{k}}^{b_{k}}*C_{a_{k-1}}^{b_{k-1}}*···*C_{a_{0}}^{b_{0}}\ (mod\ p) CabCakbkCak1bk1⋅⋅⋅Ca0b0 (mod p)

11.3.3代码
typedef long long ll;
int a,b,p;
int qmi(int a,int k)
{
	int res=1;
	while(k)
	{
		if(k&1) res=(ll)res*a%p;
		a=(ll)a*a%p;
		k>>=1;
	}
	return res;
}
int C(int a,int b)
{
	int res=1;
	for(int i=1,j=a;i<=b;i++,j--)
	{
		res=(ll)res*j%p;
		res=(ll)res*qmi(i,p-2)%p;
	}
	return res;
}
int lucas(ll a,ll b)
{
	if(a<p&&b<p) return C(a,b);
	return (ll)C(a%p,b%p)*lucas(a/p,b/p)%p;
}
11.4 分解质因数法求组合数
11.4.1内容

C a b = a ! b ! ∗ ( a − b ) ! C_a^b=\frac{a!}{b!*(a-b)!} Cab=b!(ab)!a!
分解质因数得
a ! = p 1 α 1 ∗ p 2 α 2 ∗ ⋅ ⋅ ⋅ ∗ p k α k a!=p_1^{\alpha_1}*p_2^{\alpha_2}*···*p_k^{\alpha_k} a!=p1α1p2α2⋅⋅⋅pkαk
b ! = p 1 β 1 ∗ p 2 β 2 ∗ ⋅ ⋅ ⋅ ∗ p k β k b!=p_1^{\beta_1}*p_2^{\beta_2}*···*p_k^{\beta_k} b!=p1β1p2β2⋅⋅⋅pkβk
( a − b ) ! = p 1 γ 1 ∗ p 2 γ 2 ∗ ⋅ ⋅ ⋅ ∗ p k γ k (a-b)!=p_1^{\gamma_1}*p_2^{\gamma_2}*···*p_k^{\gamma_k} (ab)!=p1γ1p2γ2⋅⋅⋅pkγk
其中,
α = ⌊ a p ⌋ + ⌊ a p 2 ⌋ + ⌊ a p 3 ⌋ + ⋅ ⋅ ⋅ \alpha=\lfloor \frac{a}{p} \rfloor+\lfloor \frac{a}{p^2} \rfloor+\lfloor \frac{a}{p^3} \rfloor+··· α=pa+p2a+p3a+⋅⋅⋅
p p p的倍数的个数+ p 2 p^2 p2的倍数的个数+···
那么,对于 C a b C_a^b Cab的某个质因数 p i p_i pi,指数为 α i − β i − γ i \alpha_i-\beta_i-\gamma_i αiβiγi

11.4.2 代码
const int N=5010;
int sum[N],primes[N],cnt;
bool st[N];
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;
		}
	}
}
int get(int n,int p)//获取指数
{
	int res=0;
	while(n)
	{
		res+=n/p;
		n/=p;
	}
	return res;
}
vector<int> mul(vector<int> a,int b)//高精度乘法
{
	vector<int> c;
	int t=0;
	for(int i=0;i<(int)a.size();i++)
	{
		t+=a[i]*b;
		c.push_back(t%10);
		t/=10;
	}
	while(t)
	{
		c.push_back(t%10);
		t/=10;
	}
	return c;
}
int main()
{
	int a,b;
	cin>>a>>b;
	get_primes(a);
	for(int i=0;i<cnt;i++)
	{
		int p=primes[i];
		sum[i]=get(a,p)-get(b,p)-get(a-b,p);
	}
	vector<int> res;
	res.push_back(1);
	for(int i=0;i<cnt;i++)
		for(int j=0;j<sum[i];j++)
			res=mul(res,primes[i]);
	for(int i=res.size()-1;i>=0;i--)
		printf("%d",res[i]);
}
11.5 卡特兰数

卡特兰数是组合数学中一个常出现于各种计数问题中的数列。其前几项为(从第0项开始):1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, …

11.5.1几何意义

给定 n n n 0 0 0 n n n 1 1 1,它们将按照某种顺序排成长度为 2 n 2n 2n的序列,求它们能排成的所有序列中,能够满足任意前缀序列中0的个数不少于1的个数的序列有多少。
转化到二维坐标中,就是求从原点 ( 0 , 0 ) (0,0) (0,0)出发到 ( n , n ) (n,n) (n,n)满足已走路径始终是右移步数多于上移步数的方案数。即路线不超过直线 y = x y=x y=x上部。

11.5.2推导

总方案数:从原点 ( 0 , 0 ) (0,0) (0,0)出发到 ( n , n ) (n,n) (n,n),需要右移 n n n步,上移 n n n步才能到达终点,方案数为 C 2 n n C_{2n}^n C2nn步。
触碰红线:即从原点 ( 0 , 0 ) (0,0) (0,0)出发到 ( n − 1 , n + 1 ) (n-1,n+1) (n1,n+1),方案数 C n − 1 2 n C_{n-1}^{2n} Cn12n
那么合法方案数: C 2 n n − C n − 1 2 n C_{2n}^n-C_{n-1}^{2n} C2nnCn12n
化简后, C a t a l a n n = 1 n + 1 ∗ C 2 n n Catalan_n=\frac{1}{n+1}*C_{2n}^n Catalann=n+11C2nn
在这里插入图片描述

12. 容斥原理
12.1基本思想

先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复,这种计数的方法称为容斥原理。
n n n个元素,奇数个加,偶数个减,一共 2 n − 1 2^n-1 2n1
∣ S 1 ∪   S 2 ∪   S 3 ∣ = ∣ S 1 ∣ + ∣ S 2 ∣ + ∣ S 3 ∣ − ∣ S 1 ∩   S 2 ∣ − ∣ S 1 ∩   S 3 ∣ − ∣ S 2 ∩   S 3 ∣ + ∣ S 1 ∩   S 2 ∩   S 3 ∣ |S_1\cup\ S_2\cup\ S_3|=|S_1|+|S_2|+|S_3|-|S_1\cap\ S_2|-|S_1\cap\ S_3|-|S_2\cap\ S_3|+|S_1\cap\ S_2\cap\ S_3| S1 S2 S3=S1+S2+S3S1 S2S1 S3S2 S3+S1 S2 S3
C n 1 − C n 2 + C n 3 − ⋅ ⋅ ⋅ + ( − 1 ) k − 1 C k k = 1 C_n^1-C_n^2+C_n^3-···+(-1)^{k-1}C_k^k=1 Cn1Cn2+Cn3⋅⋅⋅+(1)k1Ckk=1

13. 博弈论

先手必胜状态:可以走到某一个必败状态
先手必败状态:走不到任何一个必败状态

13.1Nim游戏
13.1.1 规则

有n堆石子,两个玩家轮流拿石子,每次从任意一堆中拿走任意数量的石子,不能不拿,拿到最后一个石子的玩家获胜。

13.1.2 结论

a 1 ∧ a 2 ∧ ⋅ ⋅ ⋅ ∧ a n = 0 a_1\wedge a_2\wedge···\wedge a_n=0 a1a2⋅⋅⋅an=0 先手必败
a 1 ∧ a 2 ∧ ⋅ ⋅ ⋅ ∧ a n ≠ 0 a_1\wedge a_2\wedge···\wedge a_n \neq0 a1a2⋅⋅⋅an=0 先手必胜

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值