本文共 1327 字,大约阅读时间需要 4 分钟。
链接: 来源:牛客网
第一行一个正整数T,表示数据组数。(1<=T<=10000)对于每组数据包含一行三个正整数n,m,k。
对于每组数据输出一个正整数表示答案。 由于答案可能过大,所以只需要输出对10 9+7取模后的答案
其实题目就是让你求一个01序列满足:
①总共n个1,n个0(相当于进栈和出栈);
②对于所有前缀1的个数一定要大于等于0的个数;
③额外的限制条件:在某个前缀一定满足有刚好m-1个1和m-k个数字0
如果只有前两个条件,答案刚好就是第n项
其实看第②③个条件,可以得出
④对于所有后缀0的个数一定要大于等于1的个数;
⑤在某个后缀一定满足有刚好n-(m-k)个数字0,n-m个数字1
而根据or,可以得出一个公式:
如果某个前缀一定要满足刚好有a个1和b个0,并且所有的前缀1的个数一定要大于等于0的个数,情况总数为
所以这题答案就是(条件②③)*(条件④⑤)
#include#define LL long long#define mod 1000000007LL Pow(LL a, LL b);LL C(LL m, LL n);LL Lucas(LL m, LL n);LL Fan(LL n, LL m);LL inv[2000005] = {1}, jc[2000005] = {1};int main(void){ LL T, m, n, k, i; for(i=1;i<=2000001;i++) jc[i] = (jc[i-1]*i)%mod; inv[2000001] = Pow(jc[2000001], mod-2); for(i=2000000;i>=1;i--) inv[i] = inv[i+1]*(i+1)%mod; scanf("%d", &T); while(T--) { scanf("%lld%lld%lld", &n, &m, &k); printf("%lld\n", Fan(m-1, m-k)*Fan(n-(m-k), n-m)%mod); } return 0;}LL Fan(LL n, LL m){ LL all; all = n+m; return (C(all, n)-C(all, n+1)+mod)%mod;}LL Pow(LL a, LL b){ LL ans; ans = 1; while(b) { if(b%2==1) ans = (ans*a)%mod; a = (a*a)%mod; b /= 2; } return ans;}LL C(LL n, LL m) { LL ans; if(n