洛谷P2822 组合数问题

 


 

有C(n,m)=C(n-1,m-1)+C(n-1,m) //其实跟杨辉三角是一样的

由于询问次数很多,所以要先预处理出C(2000,2000)前的值然后再读取。

因为每个测试点的k值都是唯一的,所以所有%k==0的数就是要求的答案。

储存的时候可以用前缀和的方式保存下来。

最终式子就是:C(n,m)=(C(n-1,m-1)+C(n-1,m))%k

因为是求C(0,0)到C(n,m)的值,所以结果就是ans[n][m]。

#include<iostream>
using namespace std;
int c[2005][2005],sc[2005][2005];
int main()
{
    int t,k;
    cin>>t>>k;
    for(int i=0;i<=2000;i++)
    {
        c[i][i]=1;
        c[i][0]=1;
    }
    for(int i=1;i<=2000;i++)
    {
        for(int j=1;j<=i;j++)
        {
            c[i][j]=(c[i-1][j]+c[i-1][j-1])%k;
            sc[i][j]=sc[i-1][j]+sc[i][j-1]-sc[i-1][j-1];
            if(c[i][j]==0)
                sc[i][j]++;
        }
        sc[i][i+1]=sc[i][i];
    }
    for(int i=1;i<=t;i++)
    {
        int a,b;
        cin>>a>>b;
        if(b>a)
            b=a;
        cout<<sc[a][b]<<endl;
    }
    return 0;
}

 

posted @ 2019-08-17 22:40  nenT  阅读(107)  评论(0)    收藏  举报