[BZOJ4870][SHOI2017]组合数问题 DP+矩阵快速幂

考虑这个式子的组合意义,表示从nk个物品中选取mod k=r个物品。递推式很显然咯,f[i][j]=f[i-1][j]+f[i-1][(j-1)%k]。矩阵快速幂加速一下就好了。
WA点:转移矩阵第i行是第j列和(j-1)%k列为一,所以第0行是第0列和k-1列,特别地,当k=1时,1*1矩阵中那个唯一的数应该是2,因为加了两次。
代码:

#include
#include
#include
#define ll long long
using namespace std;
ll n,r,K,mod;
struct matrix
{
    ll a[51][51];
    matrix(){memset(a,0,sizeof(a));}
    matrix operator *(const matrix &x)
    {
        matrix ans;
        for(int i=0;ifor(int j=0;jfor(int k=0;kreturn ans;         
    }
}m;
matrix ksm(matrix a,ll b)
{
    matrix re;
    for(int i=0;i1;
    for(;b;b>>=1) 
    {
        if(b&1) re=re*a;
        a=a*a;
    }
    return re;

}
int main()
{
    scanf("%lld%lld%lld%lld",&n,&mod,&K,&r);
    m.a[0][0]+=1;m.a[0][K-1]+=1;
    for(int i=1;i1]=1;
    m=ksm(m,n*K);
    printf("%lld",m.a[0][r]);   
    return 0;
}

你可能感兴趣的:(dp,线性代数,组合数学,矩阵快速幂)