一道组合数取模题

题目大意:求长度为n且每项均在[1,n]的不上升数列与不下降数列的个数和。

思路:总数就是不下降数列的个数*2-n(常数列的个数)

然后考虑不下降数列的个数

为了方便,把第0项设为0,把第n+1项设为n。

差分,然后不下降数列就是差分数组a[i]每一项大于等于0,且Σa[i]=n。

每项+1,就相当于在2n-1个空位(本来是2n+1,首尾不能放)放n个板子。

于是答案就是C(2n-1,n)*2-n

因为要取模,因为逆元可乘,所以上面和下面的阶乘都可以先乘起来再求逆元。

#include<cstdio>
#include<cstring>
#include<algorithm>
const int mod=2000003;
using namespace std;
typedef long long ll;
int n;

ll qpow(ll a,int b){
	ll res=1;
	for (ll j=a;b;j=j*j%mod,b>>=1)
		if (b&1) res=res*j%mod;
	return res;
}

void work(int n){
	ll ans,A=1,B=1;
	for (int i=n;i<=2*n-1;i++) A=A*i%mod;
	for (int i=1;i<=n;i++) B=B*i%mod;
	for (int i=0;i<mod;i++)
		if (i*B%mod==A%mod){ans=i;break;}
	ans=((ans*2-n)%mod+mod)%mod;
	printf("%I64d
",ans);
}

int main(){
	scanf("%d",&n),work(n);
	return 0;
}



原文地址:https://www.cnblogs.com/thythy/p/5493524.html