zoukankan      html  css  js  c++  java
  • [BZOJ4870/LOJ2143][Shoi2017]组合数问题

    题目链接:

    BZOJ4870 LOJ2143

    神仙思维题。

    直接推式子是找不到什么性质的,我们来考虑一下这个式子的意义:

    (nk)个物品中,选(x(xmod{k}equiv r))个物品的方案数

    那么可以DP:设(f[i][j])表示前(i)个物品,选(x(xmod{k}equiv j))个物品的方案数

    则有:(f[i][j]=f[i-1][(j-1)mod{k}]+f[i-1][j])

    那么就可以矩阵乘法优化了。

    时间复杂度 (O(k^2log n))

    注意特判(k=1)的情况

    代码:

    #include <cstdio>
    #include <cstring>
    #define rint register int
    typedef long long ll;
    
    int n,p,k,r;
    
    struct Matrix
    {
        int n,m,a[55][55];
        inline Matrix(int ns,int ms){n=ns,m=ms;memset(a,0,sizeof a);}
    
        inline Matrix operator*(const Matrix &o)const
        {
            Matrix Res(n,o.m);
            for(rint i=0;i<n;++i)
                for(rint k=0;k<m;++k)
                    for(rint j=0;j<o.m;++j)
                        Res.a[i][j]=(Res.a[i][j]+(ll)a[i][k]*o.a[k][j])%p;
            return Res;
        }
    };
    
    int main()
    {
        scanf("%d%d%d%d",&n,&p,&k,&r);
        Matrix f(1,k),g(k,k);
        f.a[0][0]=1;
        for(rint i=0;i<k;++i)++g.a[i][i],++g.a[i][(i+1)%k];//不直接赋值,防止k=1特殊情况
        for(ll b=(ll)n*k;b;b>>=1,g=g*g)if(b&1)f=f*g;
        printf("%d
    ",f.a[0][r]);
        return 0;
    }
    
  • 相关阅读:
    因特网中和多媒体有关的协议
    进程与线程
    线程模型
    SMP PVP Cluster
    读写者
    回调函数
    环境变量
    堆与栈的区别
    操作系统中的同步、异步、阻塞和非阻塞
    Razor潜入2令人疑惑的LocateOwner方法
  • 原文地址:https://www.cnblogs.com/LanrTabe/p/11496613.html
Copyright © 2011-2022 走看看