这道题算是bzoj1485的简化版,只要我们看出来这是一个catalan数就可以了。
ywq大佬在ACM的时候居然能看出来蒟蒻我真是佩服的五体投地%%%
先上/* 蒟蒻丑陋的O(n^3)打表代码 */打表代码我们通过它得出规律:
#include<cstdio>
#include<cstring>
using namespace std;
int dp[100][100];
int main()
{
int nn;
scanf("%d",&nn);
for(int n=1;n<=nn;n++){
memset(dp,0,sizeof(dp));
int ans=0;
for(int i=1;i<=n;i++)
for(int j=2*i;j<=2*n;j++){
if(i==1){
dp[i][j]=1;continue;
}
for(int k=2*(i-1);k<j;k++){
dp[i][j]+=dp[i-1][k];
}
}
for(int j=1;j<=2*n;j++)
ans+=dp[n][j];
printf("%d ",ans);
}
return 0;
}
接下来只用求Catalan数。因为N在可接受范围内我们可以O(1)求逆元。P在不可接受范围内所以就不用lucas了
#include<cstdio>
using namespace std;
const int N=2000000;
const int MOD=1e9+9;
#define ll long long
ll fac[N+5],facinv[N+5],inv[N+5];
void euler()
{
fac[0]=1,fac[1]=1,inv[1]=1,facinv[1]=1;
for(int i=2;i<=N;i++){
inv[i]=inv[MOD%i]*(MOD-MOD/i)%MOD;
facinv[i]=facinv[i-1]*inv[i]%MOD;
fac[i]=fac[i-1]*i%MOD;
}
}
ll Catalan(int n)
{
return fac[2*n]*facinv[n+1]%MOD*facinv[n]%MOD;
}
int main()
{
euler();
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
printf("%lld\n",Catalan(n/2));
}
return 0;
}