洛谷2822 组合数问题

Luogu

算法

注意到组合数的递推公式:

$c[i][j]=c[i-1][j]+c[i-1][j-1]$

所以我们可以先把$c$打出来,记得$mod\ k$。

然后判断这个数是否能被k整除,是的话就统计。

然后离线做就行了。

代码

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
typedef unsigned long long LL;
LL s[2010][2010],c[2010][2010]; //s[i][j]表示前i行j列有多少个j的约数  
LL h[2010]; //第i行有多少个k的约数  
int main()
{
    int t,k,n,m;
    scanf("%d%d",&t,&k);
    c[0][0]=1; //边界:C(0,0)=1; 
    for (int i=1;i<=2001;i++)
    {
        c[i][0]=1; //边界:C(i,0)=1 
        for (int j=1;j<=i;j++)
        {
            c[i][j]=(c[i-1][j]+c[i-1][j-1])%k; //递推  
            if (c[i][j]%k==0) h[i]++; //处理约数  
            s[i][j]=s[i-1][j]+h[i]; //累加s[i][j]
            if (i==j) s[i][j]=s[i-1][j-1]+h[i]; //这里要特判  
        } 
    }
    while (t--)
    {
        scanf("%d%d",&n,&m);
        if (m>n) m=n; //注意特判 
        printf("%d\n",s[n][m]);
    }
    return 0;
}
最后修改:2019 年 09 月 23 日 10 : 06 PM

发表评论