【loj6142】「2017 山东三轮集训 Day6」A 结论题+Lucas定理

本文探讨了一个关于集合中偶数个偶数计数的问题,并给出了针对不同情况的解答公式。利用Lucas定理求解大规模组合数问题,并提供了一种通过编程实现的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

JOHNKRAM 最近在研究集合。他从 $[1,2n]$ 中任选了 $n$ 个不同的整数,组成了 $\binom{2n}{n} $ 个不同的集合。现在他想知道,在这些集合中,有多少个集合含有偶数个偶数?答案可能很大,你只需要告诉他答案 $\text{mod}\ 1000003$ 的结果即可。

$n\le 10^{18}$ 。


题解

结论题+Lucas定理

结论:

1. 当 $n$ 为奇数时,答案为 $\frac{\binom{2n}{n}}2$ ;

2. 当 $n$ 为偶数且为 $4$ 的倍数时,答案为 $\frac{\binom{2n}{n}+\binom{n}{\frac n2}}2$ ;

3. 当 $n$ 为偶数且不为 $4$ 的倍数时,答案为 $\frac{\binom{2n}{n}-\binom{n}{\frac n2}}2$ ;

我不会证明...打表打出来的...

然后使用Lucas定理求组合数即可。

另外本题好像还可以用数位dp来做。

#include <cstdio>
#define mod 1000003
#define inv2 500002
typedef long long ll;
ll fac[mod] , inv[mod] , fin[mod];
ll C(ll n , ll m)
{
	if(n < m) return 0;
	else if(n <= mod) return fac[n] * fin[m] % mod * fin[n - m] % mod;
	else return C(n / mod , m / mod) * C(n % mod , m % mod) % mod;
}
int main()
{
	ll n;
	int i;
	fac[0] = fac[1] = inv[1] = fin[0] = fin[1] = 1;
	for(i = 2 ; i < mod ; i ++ )
	{
		fac[i] = fac[i - 1] * i % mod;
		inv[i] = (mod - mod / i) * inv[mod % i] % mod;
		fin[i] = fin[i - 1] * inv[i] % mod;
	}
	scanf("%lld" , &n);
	if(n & 1) printf("%lld\n" , C(2 * n , n) * inv2 % mod);
	else if(n & 2) printf("%lld\n" , (C(2 * n , n) - C(n , n / 2) + mod) * inv2 % mod);
	else printf("%lld\n" , (C(2 * n , n) + C(n , n / 2)) * inv2 % mod);
	return 0;
}

 

转载于:https://www.cnblogs.com/GXZlegend/p/8626420.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值