数学(三):高斯消元、求组合数

高斯消元

原理:

例题:高斯消元解线性方程组

输入一个包含 n 个方程 n 个未知数的线性方程组。

方程组中的系数为实数。

求解这个方程组。

下图为一个包含 mm 个方程 nn 个未知数的线性方程组示例:

9a504fc2d5628535be9dcb5f90ef76c6a7ef634a.gif

输入格式

第一行包含整数 n。

接下来 n 行,每行包含 n+1个实数,表示一个方程的 n 个系数以及等号右侧的常数。

输出格式

如果给定线性方程组存在唯一解,则输出共 n 行,其中第 i 行输出第 i 个未知数的解,结果保留两位小数。

如果给定线性方程组存在无数解,则输出 Infinite group solutions

如果给定线性方程组无解,则输出 No solution

数据范围

1≤n≤100
所有输入系数以及常数均保留两位小数,绝对值均不超过 100。

输入样例:

3
1.00 2.00 -1.00 -6.00
2.00 1.00 -3.00 -9.00
-1.00 -1.00 2.00 7.00

输出样例:

1.00
-2.00
3.00

 解题:

#include 
#include 
#include using namespace std;const int N=110;
const double eps=1e-6;int n;
double a[N][N];int gauss()
{int c,r;//c:枚举的哪一列,r:表示哪行for(c=0,r=0;cfabs(a[t][c]))t=i;if(abs(a[t][c])=c;i--) a[r][i]/=a[r][c];//把该列第一个数变成1,倒着来for(int i=r+1;ieps)for(int j=n;j>=c;j--)a[i][j]-=a[r][j]*a[i][c];r ++;}if(reps)return 2;//无解return 1;//有无穷解        }for (int i = n - 1; i >= 0; i -- )//倒着把方程消一边for (int j = i + 1; j < n; j ++ )a[i][n] -= a[j][n] * a[i][j];return 0;//有唯一解
}int main()
{cin>>n;for(int i=0;i>a[i][j];int t=gauss();if(t ==0){for(int i=0;i

求组合数

1.    10万组 1<=b<=a<=2000 递归

 例题:求组合数 I

给定 n 组询问,每组询问给定两个整数 a,b请你输出 Cbamod(109+7)的值。

输入格式

第一行包含整数 n。

接下来 n 行,每行包含一组 a 和 b。

输出格式

共 n 行,每行输出一个询问的解。

数据范围

1≤n≤10000
1≤b≤a≤2000

输入样例:

3
3 1
5 3
2 2

输出样例:

3
10
1

解题代码:

#include 
#include using namespace std;const int N=2010,mod=1e9+7;int c[N][N];void init()
{for(int i=0;i

2.  1万 1<=b<=a<=10^5  预处理

 例题:求组合数 II

给定 n 组询问,每组询问给定两个整数 a,b,请你输出 Cbamod(109+7)的值。

输入格式

第一行包含整数 n。

接下来 n 行,每行包含一组 a 和 b。

输出格式

共 n 行,每行输出一个询问的解。

数据范围

1≤n≤10000
1≤b≤a≤105

输入样例:

3
3 1
5 3
2 2

输出样例:

3
10
1

解题:

#include 
#include using namespace std;const int N=100010,mod=1e9+7;typedef long long LL;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;//0的阶乘都是1for(int i=1;i

3.    20组  1<=b<=a<=10^18   1<=p<=10^5   卢卡斯定理

 

例题:求组合数 III

给定 n 组询问,每组询问给定三个整数 a,b,p,其中 p 是质数,请你输出 CbamodpCabmodp 的值。

输入格式

第一行包含整数 n。

接下来 n 行,每行包含一组 a,b,p

输出格式

共 n 行,每行输出一个询问的解。

数据范围

1≤n≤20
1≤b≤a≤1018
1≤p≤105

输入样例:

3
5 3 7
3 1 5
6 4 13

输出样例:

3
3
2

解题:

#include 
#include using namespace std;typedef long long LL;int 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>n;while(n--){LL a,b;cin >>a>>b>>p;cout <

 4.  结果很大,需要使用高精度计算

例题:求组合数 IV

输入 a,b,求 Cba的值。

注意结果可能很大,需要使用高精度计算。

输入格式

共一行,包含两个整数 a 和 b。

输出格式

共一行,输出 Cba 的值。

数据范围

1≤b≤a≤5000

输入样例:

5 3

输出样例:

10

解题:

#include 
#include 
#include using namespace std;const int N=5010;int primes[N],cnt;
int sum[N];
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) //存n的阶乘里面包含p的个数
{int res=0;while(n){res+=n/p;n/=p;}return res;
}vector mul(vector a,int b)
{vector c;int t=0;for(int i=0;i>a>>b;get_primes(a);//先预处理除a里面所有的质数for(int i=0;i res;res.push_back(1);for(int i=0;i=0;i--) printf("%d",res[i]);puts("");return 0;}

 5. 卡特兰数

例题:满足条件的01序列

给定 n 个 0 和 n 个 1,它们将按照某种顺序排成长度为 2n的序列,求它们能排列成的所有序列中,能够满足任意前缀序列中 0 的个数都不少于 1 的个数的序列有多少个。

输出的答案对 109+7 取模。

输入格式

共一行,包含整数 n。

输出格式

共一行,包含一个整数,表示答案。

数据范围

1≤n≤105

输入样例:

3

输出样例:

5

解题:

 

 

#include 
#include using namespace std;typedef long long LL;
const int mod=1e9+7;//快速幂
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()
{int n;cin>>n;int a=2*n,b=n;int res=1;for(int i=a;i>a-b;i--) res=(LL)res*i%mod;for(int i=1;i<=b;i++) res=(LL)res*qmi(i,mod-2,mod)%mod;res=(LL)res*qmi(n+1,mod-2,mod)%mod;cout<


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章