• [SCOI2010]字符串


    题目:BZOJ1856、洛谷P1641、codevs2418。

    题目大意:给你n个1和m个0,让你用它们组成长度为n+m的串,问有多少串满足,它的任意前缀中的1总是不少于0(答案mod20100403)。

    解题思路:这题和字符串一点关系也没有!!

    首先我们可以把题目转化为:从0,0走到n+m,n-m,每次可以走(1,1)或(1,-1),求不经过直线y=-1的方案数。

    我们先不考虑“不经过直线y=-1”的限制,那么方案数为$C^{m}_{n+m}$。

    现在我们考虑不满足条件的方案数,其实就相当于从-2,0走到n+m,n-m的方案数,所以方案数为$C^{m-1}_{n+m}$。

    所以答案就为“总方案数-不满足条件的方案数”。

    $$egin{align}C^m_{n+m}-C^{m-1}_{n+m}&=&frac{(n+m)!}{n!m!}-frac{(n+m)!}{(n+1)!(m-1)!}\&=&frac{(n+m)!(n+1)-(n+m)!m}{(n+1)!m!}\&=&frac{(n-m+1)(n+m)!}{(n+1)!m!}\&=&(n-m+1)frac{(n+2)(n+3)...(n+m)}{m!}\&=&(n-m+1)(n+2)(n+3)...(n+m)÷1÷2÷...÷mend{align}$$

    由于用到取模运算,还要除以1~m,所以需要用到逆元。

    既然需要1~m的所有逆元,而且模数是个质数,那就用线性推逆元好了。

    可惜的是,在推逆元的时候乘法超int,没有转化为long long,导致没有一发AC。

    C++ Code:

    #include<cstdio>
    using namespace std;
    #define p 20100403
    int n,m,fact,inv[1000005];
    int main(){
    	scanf("%d%d",&n,&m);
    	int ans=1;
    	inv[1]=1;
    	for(int i=2;i<=m;++i)
    	inv[i]=(long long)(p-p/i)*inv[p%i]%p;
    	for(int i=2;i<=m;++i)ans=(long long)ans*(i+n)%p;
    	ans=(long long)ans*(n-m+1)%p;
    	for(int i=1;i<=m;++i)
    	ans=(long long)ans*inv[i]%p;
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    [SCOI2003]严格N元树
    CF280 C. Game on Tree
    [HDU2281]Square Number
    [HDU5391]Zball in Tina Town
    [HDU3988]Harry Potter and the Hide Story
    [HDU5794]A Simple Chess
    [HDU5451]Best Solver
    [HDU1724]Ellipse
    [HDU6304]Chiaki Sequence Revisited
    [HDU6343]Graph Theory Homework
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/7381610.html
Copyright © 2020-2023  润新知