[SCOI2010]生成字符串
XiaoX早就切了Orz
这道题是个组合数学题。
里面用到了卡特兰数的思想。
我们可以把这个操作放到坐标系上,一开始有个点在(0,0),然后把1看作(+1,+1),0看做(+1,-1)
然后我们就可以把问题视作从(0,0)出发,到(n+m,n-m),不经过y=-1的方案数。
经过y=-1的就可以对称一下,看作从(0,-2)开始,到(n+m,n-m)的方案数即可,由于要走n+m步,有n-m+1个1,m-1个0,所以最后答案是 C(n+m,m)-C(n+m,m-1)。
代码:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int mod=20100403; const int N=2000005; long long n,m,fac[N],inv[N]; long long ksm(long long d,long long z) { long long res=1; while(z) { if(z&1) res=1ll*res*d%mod; d=1ll*d*d%mod; z>>=1; } return res; } int main() { cin>>n>>m; fac[0]=1; for(int i=1;i<=n+m;i++) fac[i]=1ll*fac[i-1]*i%mod; inv[n+m]=ksm(fac[n+m],mod-2); for(int i=n+m-1;i;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod; inv[0]=1; cout<<1ll*fac[n+m]*(1ll*inv[n]*inv[m]%mod-1ll*inv[n+1]*inv[m-1]%mod+mod)%mod; return 0; }
我是咸鱼。转载博客请征得博主同意Orz