1. 程式人生 > >[SCOI2010]生成字符串

[SCOI2010]生成字符串

字符串 最終 scoi2010 () urn const char n+2 logs

OJ題號:

BZOJ1856、洛谷1641

思路:

總方案數為$\binom{n+m}{m}$,非法方案數為$\binom{n+m}{m-1}$。
則合法方案數為$(n-m+1)\frac{(n+2)(n+3)...(n+m)}{m!}$。
其中除以$m!$可以用乘以逆元實現,邊乘邊模。
因為要求出1~m的連續的逆元,所以可以線性推。
另外註意中間結果和最終乘積可能會超過int範圍,所以要轉long long,不然只有10分。

 1 #include<cstdio>
 2 #include<cctype>
 3 inline int getint() {
4 char ch; 5 while(!isdigit(ch=getchar())); 6 int x=ch^0; 7 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^0); 8 return x; 9 } 10 const int mod=20100403; 11 int main() { 12 int n=getint(),m=getint(); 13 long long sum=n-m+1; 14 for(int i=2;i<=m;i++) {
15 sum=sum*(n+i)%mod; 16 } 17 int inv[m+1]; 18 inv[1]=1; 19 for(int i=2;i<=m;i++) { 20 inv[i]=(long long)(mod-mod/i)*inv[mod%i]%mod; 21 sum=sum*inv[i]%mod; 22 } 23 printf("%lld\n",sum); 24 return 0; 25 }

[SCOI2010]生成字符串