列表

详情


NC15077. 造一造

描述

WYF正试图用一个栈来构造一棵树,现在他已经构造了n个元素作为树的节点,只要将这n个元素依次入栈出栈就可以形成一棵树了。当然,这个问题与树并没有关系,所以它叫做WYF的栈。每次你可以入栈一个新元素或者当栈非空时出栈一个元素,n个元素必须依次入栈,而WYF希望其中第m个元素入栈之后,栈中恰好有k个元素,现在他想知道一共有多少种入栈出栈顺序满足这个条件。

输入描述

第一行一个正整数T,表示数据组数。(1<=T<=10000)
对于每组数据包含一行三个正整数n,m,k。

输出描述

 对于每组数据输出一个正整数表示答案。
 由于答案可能过大,所以只需要输出对109+7取模后的答案

示例1

输入:

2
3 3 3
3 3 2

输出:

1
2

示例2

输入:

5
10 3 2
10 2 2
10 7 5
10 6 2
10 7 6

输出:

6864
11934
2200
3780
924

示例3

输入:

2
5 4 4
5 2 1

输出:

5
14

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 131ms, 内存消耗: 47712K, 提交时间: 2018-10-15 22:55:52

#include <bits/stdc++.h>
#define M 1000000007
#define ll long long
#define N 2000005
using namespace std;
ll fac[N]={1,1},inv[N]={1,1},f[N]={1,1};
void init()
{
    for(int i=2;i<N;i++)
    {
        fac[i]=fac[i-1]*i%M;
        f[i]=(M-M/i)*f[M%i]%M;
        inv[i]=inv[i-1]*f[i]%M;
    }
}
ll C(ll a,ll b)
{
    if(b>a)
        return 0;
    return fac[a]*inv[b]%M*inv[a-b]%M;
}
ll Cata(ll a,ll b)
{
    return (C(a+b,a)-C(a+b,a+1)+M)%M;
}
int main()
{
	ios::sync_with_stdio(false);
	ll T,n,m,k,ans;
	init();
	cin>>T;
	while(T--)
    {
        cin>>n>>m>>k;
        ans=Cata(m-1,m-k)%M*Cata(k+n-m,n-m)%M;
        //*(k+1)%M*(n-m+1)%M;
        cout<<ans<<endl;
    }
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 61ms, 内存消耗: 16472K, 提交时间: 2020-05-11 20:31:31

#include<iostream>
using namespace std;
const int MD=1e9+7,N=2e6+5;
int f[N],v[N];
int C(int n,int m){
    if(m<0||m>n) return 0;
    return 1LL*f[n]*v[m]%MD*v[n-m]%MD;
}
int F(int n,int m){
    return (C(n+m,m)-C(n+m,m-1)+MD)%MD;
}
int main(){
    v[0]=v[1]=f[0]=f[1]=1;
    for(int i=2; i<N; i++) f[i]=1LL*f[i-1]*i%MD,v[i]=1LL*v[MD%i]*(MD-MD/i)%MD;
    for(int i=2; i<N; i++) v[i]=1LL*v[i-1]*v[i]%MD;
    int n,m,k,T;
    scanf("%d",&T);
    while (T--){
        scanf("%d%d%d",&n,&m,&k);
        printf("%d\n",1LL*F(m-1,m-k)*F(n-m+k,n-m)%MD);
    }
return 0;
}

上一题