zoukankan      html  css  js  c++  java
  • BZOJ 4870 组合数问题

    嗯。。。。这个式子很奇妙

    化简是没有用的,考虑一个dp,答案能用这个式子表达。

    于是dp[i][j]表示前i组物品选出%k=j个物品的方案数,然后矩阵加速转移。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    long long n,p,k,r,c[55][55];
    struct matrix
    {
        long long a[55][55];
    }ans,base;
    matrix operator * (matrix a,matrix b)
    {
        matrix c;
        for (long long i=0;i<k;i++)
            for (long long j=0;j<k;j++)
                c.a[i][j]=0;
        for (long long i=0;i<k;i++)
            for (long long j=0;j<k;j++)
                for (long long kk=0;kk<k;kk++)
                    c.a[i][j]=(c.a[i][j]+a.a[i][kk]*b.a[kk][j]%p)%p;
        return c;
    }
    void build()
    {
        c[0][0]=1;
        for (long long i=1;i<=k;i++)
        {
            c[i][0]=1;
            for (long long j=1;j<=i;j++) c[i][j]=(c[i-1][j-1]+c[i-1][j])%p;
        }
        base.a[0][0]=2;for (long long i=1;i<k;i++) base.a[i][0]=c[k][k-i];
        for (long long i=1;i<k;i++)
            for (long long j=0;j<k;j++)
                base.a[j][i]=base.a[(j-1+k)%k][i-1];
        ans.a[0][0]=2;for (long long i=1;i<k;i++) ans.a[0][i]=c[k][i];
    }
    void f_pow(long long x)
    {
        while (x)
        {
            if (x&1) ans=(ans*base);
            base=base*base;
            x>>=1;
        }
    }
    int main()
    {
        scanf("%lld%lld%lld%lld",&n,&p,&k,&r);
        build();
        f_pow(n-1);
        printf("%lld
    ",ans.a[0][r]);
        return 0;
    }
  • 相关阅读:
    React之JSX语法
    Visual Studio Code 使用 Typings 实现智能提示功能
    React.js 之hello word
    Linux命令详解-cd
    Linux命令详解-ls
    linux常用命令
    LINUX系统配置相关
    netsh
    Visual Studio
    乘法算术表
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/7794484.html
Copyright © 2011-2022 走看看