【BZOJ4402】Claris的剑(组合计数)
题意:
给定数列的定义:
1.每个元素都是正整数
2.每个元素不能超过M
3.相邻两个元素的差的绝对值必须是1
4.第一个元素的值必须是1
求有多少个长度不超过N的合法的本质不同的序列
两个序列本质不同,当且仅当存在至少一个数值,在两个序列中出现次数不一样
比如{1,2,3}和{1,3,2}是本质相同的
{1,2,3}和{1,2,1}则是本质不同的
答案对1e9+7取模
N,M<=2e6
思路:From https://blog.csdn.net/ws_yzy/article/details/50753724
1 #include<cstdio> 2 typedef long long ll; 3 using namespace std; 4 #define MOD 1000000007 5 #define N 2100000 6 ll fac[N],inv[N]; 7 8 9 ll c(int x,int y) 10 { 11 return fac[x]*inv[y]%MOD*inv[x-y]%MOD; 12 } 13 14 ll calc(int x,int y) 15 { 16 if(x<0) return 0; 17 if(x==0||x==1) return 1; 18 return c(x/2+y,y); 19 } 20 21 int main() 22 { 23 int n,m; 24 scanf("%d%d",&n,&m); 25 fac[0]=1; 26 for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%MOD; 27 inv[0]=inv[1]=1; 28 for(int i=2;i<=n;i++) inv[i]=inv[MOD%i]*(MOD-MOD/i)%MOD; 29 for(int i=1;i<=n;i++) inv[i]=inv[i]*inv[i-1]%MOD; 30 ll ans=0; 31 if(n&&m) ans++; 32 for(int i=2;i<=m;i++) 33 { 34 ans=(ans+calc(n-i,i-1))%MOD; 35 ans=(ans+calc(n-i-1,i-1))%MOD; 36 } 37 printf("%lld\n",ans); 38 return 0; 39 } 40 41
null