zoukankan      html  css  js  c++  java
  • 【Luogu】P3746组合数问题(矩阵)

      题目链接

      哇我一个活人的智商被题目碾压了

      可以把问题转化为有nk个物品,问拿i件物品的方案数有多少种,其中i%k=r。

      然后矩阵乘法加速DP即可。

      

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cctype>
    #define maxn 55
    using namespace std;
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    int m;long long mod,n,r;
    
    struct Matrix{
        long long s[maxn][maxn];
        void clear(){memset(s,0,sizeof(s));}
        Matrix operator *(Matrix a){
            Matrix ans;    ans.clear();
            for(int i=1;i<=m;++i)
                for(int j=1;j<=m;++j)
                    for(int k=1;k<=m;++k)    ans.s[i][j]=(ans.s[i][j]+s[i][k]*a.s[k][j]%mod)%mod;
            return ans;
        }
    }start,d;
    
    Matrix Pow(Matrix a,long long b){
        Matrix ret;    ret.clear();
        for(int i=1;i<=m;++i)    ret.s[i][i]=1;
        while(b){
            if(b&1)    ret=ret*a;
            a=a*a;
            b>>=1;
        }
        return ret;
    }
    
    int main(){
        start.clear();
        n=read();mod=read();m=read();r=read();
        //start.s[1][m]=1;
        for(int i=1;i<=m;++i)
            start.s[i][i]++,start.s[(i-2+m)%m+1][i]++;
        n*=m;
        start=Pow(start,n);
        d.s[1][1]=1;
        d=d*start;
        printf("%lld
    ",d.s[1][r+1]);
        return 0;
    }
  • 相关阅读:
    POJ1806 Manhattan 2025
    POJ1258 AgriNet【最小生成树】
    POJ1789 Truck History【最小生成树】【终于AC了】
    memset的用法
    HDOJ1106 排序
    POJ2965
    414某OJ竞赛题
    HDOJ1745 I hate it【线段树】
    HDOJ2795 Billboard【线段树】
    蓝桥杯o(︶︿︶)o 唉
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/8807480.html
Copyright © 2011-2022 走看看