题解 | 小红的连续段
小红的连续段
https://www.nowcoder.com/practice/252310f0f8cd4101be25517652fc5bdf
考虑x+y长度的字符串被分成了n块
1、n=2k
那么一定是k块为a,k块为b,考虑把长度为x的字符串分成k块,也就是x-1个空隙插入k-1个隔板,方案是C(x-1, k-1)。长度为y的字符串分成k块同理,然后可以先是a也可以先是b,所以答案是2*C(x-1, k-1)*C(y-1, k-1)
2、n=2k+1
那么可能是k+1块a,k块b或者反过来,思路类似上面算出方案数
#include <iostream>
#include <vector>
using namespace std;
const int mod=1000000007;
vector<int> jc(2001), inv(2001);
inline int ksm(int p, int x){
int s=1;
while(x){
if(x&1) s=1ll*s*p%mod;
p=1ll*p*p%mod;
x>>=1;
}
return s;
}
inline int C(int n, int m){
return 1ll*jc[n]*inv[m]%mod*inv[n-m]%mod;
}
int main() {
jc[0]=inv[0]=1;
for(int i=1; i<=2000; ++i){
jc[i]=1ll*jc[i-1]*i%mod;
inv[i]=ksm(jc[i],mod-2);
}
int x, y;
cin >> x >> y;
for(int i=1; i<=x+y; ++i){
int ans=0;
if(i==1) cout << "0\n";
else if(i&1){
int a=i/2;
int b=i-a;
if(b<=y && a<=x){
ans=1ll*C(y-1,b-1)*C(x-1,a-1)%mod;
ans%=mod;
}
if(b<=x && a<=y){
ans+=1ll*C(x-1,b-1)*C(y-1,a-1)%mod;
ans%=mod;
}
cout << ans << '\n';
}
else{
int a=i/2;
if(a<=x && a<=y)
ans=2ll*C(x-1,a-1)*C(y-1,a-1)%mod;
cout << ans << '\n';
}
}
}
查看8道真题和解析
