zoukankan      html  css  js  c++  java
  • [BZOJ 4870][SHOI&SXOI2017]组合数问题(Dp+矩阵优化)

    Description

    Solution

    其实看到数据范围应该往矩阵乘法这边想的

    考虑式子的实际意义 从n*k个里面选模k等于r个的方案数 Dp

    f[i][j]=f[i-1][j]+f[i-1][(j-1+k)%k]

    另外给矩阵赋值的时候建议  m.a[(i-1+K)%K][i]++; m.a[i][i]++; 而不是  m.a[(i-1+K)%K][i]=1; m.a[i][i]=1; 

    因为K=1的时候会出现偏差…a[0][0]应该为2

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    using namespace std;
    typedef long long LL;
    LL n,r,K,p;
    struct Matrix
    {
        LL a[51][51];
        Matrix(){memset(a,0,sizeof(a));}
        Matrix operator *(const Matrix& x)
        {
            Matrix ans;
            for(int i=0;i<K;i++)
            {
                for(int j=0;j<K;j++)
                {
                    for(int k=0;k<K;k++)
                    {
                        ans.a[i][j]+=(a[i][k]*x.a[k][j])%p;
                        ans.a[i][j]%=p;
                    }
                }
            }
            return ans;
        }
    }m;
    Matrix pow(Matrix a,LL n)
    {
        Matrix res;
        for(int i=0;i<K;i++)res.a[i][i]=1;
        while(n)
        {
            if(n&1)res=res*a;
            a=a*a;
            n>>=1;
        }
        return res;
    }
    int main()
    {
        scanf("%lld%lld%lld%lld",&n,&p,&K,&r);
        for(int i=0;i<K;i++)
        {
            m.a[(i-1+K)%K][i]++;
            m.a[i][i]++;
        }
        Matrix res=pow(m,1LL*n*K);
        printf("%lld
    ",res.a[0][r]);
        return 0;
    } 
  • 相关阅读:
    【自学php】第三天
    【自学php】第二天
    【自学php】第一天-macbook上配置php
    js数值转换
    js题
    【练习】响应式布局
    6.数据查询
    5.删除数据
    4.更新数据
    3.插入数据
  • 原文地址:https://www.cnblogs.com/Zars19/p/6796101.html
Copyright © 2011-2022 走看看