题解报告`排列组合 (组合 + 牡牛和牝牛 + 方程的解) 7/30

这篇博客涵盖了三个算法问题:使用Lucas定理解决大数组合取模问题;通过枚举牡牛数量解决牛的排列约束问题;以及利用插板法解决不定方程的正整数解计数。每个问题都提供了思路和样例解答,并涉及组合数学和高精度计算。
摘要由CSDN通过智能技术生成

[1]组合
题目描述
给出组合数 C(n,m) 表示从 n 个元素中选出 m 个元素的方案数。例如 C(5,2)=10,C(4,2)=6。可是当 n,m 比较大的时候,C(n,m) 很大。于是 xiaobo 希望你输出C(n,m)modp 的值。
输入
输入数据第一行是一个正整数 T,表示数据组数;

接下来是 T 组数据,每组数据有 3 个正整数 n,m,p。

对于所有数据,T≤100,1≤m≤n≤109,m≤104,m<p<109,p 是素数。

输出
对于每组数据,输出一个正整数,表示 C(n,m)modp 的结果。
样例输入
2
5 2 3
5 2 61
样例输出
1
10
思路:
Lucas定理模板题,
因为n,m的值太大所以要简化运算, C(m, n) = C(m mod p, n mod p) * C(m / p, n / p) (mod p)

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;

ll fpow(ll a,ll b,ll n){
   
	if(b==1) return a;
	if(b%2 == 1){
   
		ll t = fpow(a,b/2,n);
		t = t * t % n;
		t = t * a % n;
		return t; 
	}
	else{
   
		ll t = fpow(a,b/2,n);
		t = t * t % n;
		return t;
	}
} 

ll comb(ll n,ll m,ll p){
   
	if(m>n)return 0;
	if(m==0)return 1;
	ll up = 1 ,down = 1;
	for(ll i = 1 ; i <= m ; i++){
   
		up = (up * (n-i+1)) % p;
		down = (down * i) % p ; 
	} 
	return up * fpow(down,p-2,p) % p
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值