VIJOS1420Valentine’s Seat

题目大意

可以给排列成n+1行m+1列矩阵的椅子上色。其中,第一行所有的椅子都已上好粉红色,第一列从第2个开始的椅子都已上好天蓝色。对于其他的椅子,应保证,它的颜色和它左边的或上面的椅子颜色相同。求染色的方案数模19900801的值。

分析

通过画图或者打表,我们可以发现,最终矩阵肯定被分成2个色块,粉红色块位于矩阵右上方,天蓝色块位于矩阵左下方。每一种染色方案都一一对应于一条从n+1行m+1列的格点地图的左上角走到到右下角的路径方案。

如下图,在一个有5+1行6+1列的地图中,紫色方框中的是可以染色的椅子,这种染色方案便对应于从方框左上角走到右下角的一条路径。

记方框左上角坐标为(1,1),则右下角坐标为(n+1,m+1)
经过格点(x,y) (x<=n,y<=m+1)等价于第x+1行椅子有y-1个蓝色。

因此n+1行m+1列椅子染色方案数相当于格点地图路径数,即为:C(n+m,n)
由于19900801是个质数,因此我们直接求逆元算组合数就可以了。时间复杂度O(n)。

代码

#include<cstdio>
const int mo=19900801;
int n,m;
long long ans;
int ant(int x){
    long long a=x,ans=1;
    int p=mo-2;
    while (p){
        if (p&1)
            ans=(ans*a)%mo;
        p>>=1;
        a=(a*a)%mo;
    }
    return ans;
}
int main(){
    scanf("%d%d",&n,&m);
    m+=n;
    ans=1;
    for (int i=1;i<=n;i++)
        ans=(ans*(m-i+1))%mo;
    for (int i=2;i<=n;i++)
        ans=(ans*ant(i))%mo;
    printf("%d\n",ans);
    return 0;
}

你可能感兴趣的:(组合数学,vijos)