• bzoj1856 [ SCOI2010 ] -- 卡特兰数


    其实就是卡特兰数的定义。。。

    将放置一个1视为(1,1),放置一个0视为(1,-1)

    则答案就是从(0,0)出发到(n+m,n-m)且不经过y=-1的方案数。

    从(0,0)出发到(n+m,n-m)的总方案数是C(n+m,n)。

    若一条路径经过y=-1,那么将其从(0,0)到y=-1的一段路径以y=-1作对称,就变成了一条从(0,-2)到(n+m,n-m)的路径。

    设走了x步(1,1),y步(1,-1),则:x+y=n+m,x-y=n-m+2,解得x=n+1,y=m-1.

    那么答案就是C(n+m,n)-C((n-1)+(m-1),n+1)=C(n+m,n)-C(n+m,n+1)

    因为有取模,所以还需要求逆元。

    递推公式:inv[i]=inv[p%i]*(p-p/i)%p,要将inv[0]和inv[1]初始化为1

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 #define M 20100403
     6 #define ll long long
     7 int i,j,k,n,m,x,y,inv[1000010];
     8 inline int _Max(int x,int y){return x<y?y:x;}
     9 inline ll C(int x,int y){
    10     ll Ans=x+1;
    11     for(int i=2;i<=y;i++)Ans=(Ans*(x+i)%M)*inv[i]%M;
    12     return Ans;
    13 }
    14 int main()
    15 {
    16     scanf("%d%d",&n,&m);
    17     for(inv[0]=inv[1]=1,i=2;i<=m;i++)inv[i]=1ll*inv[M%i]*(M-M/i)%M;
    18     printf("%lld",(C(n,m)-C(n+1,m-1)+M)%M);
    19     return 0;
    20 }
    bzoj1856
  • 相关阅读:
    写在“开张”时
    上班真累
    版本控制
    电脑主板报警声音的故障现象对照表
    js页面打开倒计时
    js中的词法分析
    修改mysql数据库密码
    上班的感受
    能力是被逼出来的!!有压力才有动力
    js中绑定事件的三种方式
  • 原文地址:https://www.cnblogs.com/gjghfd/p/6552261.html
Copyright © 2020-2023  润新知