• bzoj4870: [Shoi2017]组合数问题(DP+矩阵乘法优化)


      为了1A我居然写了个暴力对拍...

      那个式子本质上是求nk个数里选j个数,且j%k==r的方案数。

      所以把组合数的递推式写出来f[i][j]=f[i-1][j]+f[i-1][(j-1+k)%k]...我们知道求组合数实际上是可以矩阵乘法优化的,只是没必要,但是这个时候就用上了...

      于是矩阵乘法优化,AC之~

    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio> 
    #include<algorithm>
    #define ll long long 
    #define MOD(x) ((x)>=p?(x)-p:(x))
    using namespace std;
    const int maxn=310,inf=1e9;
    typedef ll mtx[60][60];
    int n,p,K,r;
    mtx f,g;
    void read(int &k)
    {
        int f=1;k=0;char c=getchar();
        while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
        while(c<='9'&&c>='0')k=k*10+c-'0',c=getchar();
        k*=f;
    }
    void mul(mtx &a,mtx b)
    {
        mtx c;memset(c,0,sizeof(c));
        for(int i=1;i<=K;i++)
        for(int j=1;j<=K;j++)
        for(int k=1;k<=K;k++)
        c[i][j]=(c[i][j]+a[i][k]*b[k][j])%p;
        memcpy(a,c,sizeof(c));
    }
    void power(ll b)
    {
        for(;b;mul(f,f),b>>=1)
        if(b&1)mul(g,f);
    }
    int main()
    {
        read(n);read(p);read(K);read(r);
        for(int i=1;i<=K;i++)g[i][i]=1,f[i][i]=1;
        for(int i=1;i<=K;i++)f[i][(i-2+K)%K+1]++;
        power(1ll*n*K);
        printf("%lld
    ",g[r+1][1]);
    }
    View Code
  • 相关阅读:
    iOS UILable 自定义高度 用masony适配
    iOS上架所需图片大小明细
    GCD倒计时
    iOS 小知识汇总
    七、Swift 枚举 Enumerations
    C语言深度剖析笔记
    六、闭包 Closures
    经济学常识
    Mac小技巧
    五、函数 Functions
  • 原文地址:https://www.cnblogs.com/Sakits/p/7627054.html
Copyright © 2020-2023  润新知