题目描述
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来做
1 #include <cstdio> 2 #define mod 1000003 3 #define inv2 500002 4 typedef long long ll; 5 ll fac[mod] , inv[mod] , fin[mod]; 6 ll C(ll n , ll m) 7 { 8 if(n < m) return 0; 9 else if(n <= mod) return fac[n] * fin[m] % mod * fin[n - m] % mod; 10 else return C(n / mod , m / mod) * C(n % mod , m % mod) % mod; 11 } 12 int main() 13 { 14 ll n; 15 int i; 16 fac[0] = fac[1] = inv[1] = fin[0] = fin[1] = 1; 17 for(i = 2 ; i < mod ; i ++ ) 18 { 19 fac[i] = fac[i - 1] * i % mod; 20 inv[i] = (mod - mod / i) * inv[mod % i] % mod; 21 fin[i] = fin[i - 1] * inv[i] % mod; 22 } 23 scanf("%lld" , &n); 24 if(n & 1) printf("%lld\n" , C(2 * n , n) * inv2 % mod); 25 else if(n & 2) printf("%lld\n" , (C(2 * n , n) - C(n , n / 2) + mod) * inv2 % mod); 26 else printf("%lld\n" , (C(2 * n , n) + C(n , n / 2)) * inv2 % mod); 27 return 0; 28 }