• [六省联考2017]组合数问题


    题目大意:求这个式子:

    i=0Cik+rnk(modp)

    这道题就是个数学题,做法其实就是优化的暴力——杨辉三角矩阵加速。
    可以加速的原理,其实就是杨辉三角是一个一维递推,并且可以将递推描述为:复制矩阵到一个新矩阵,然后矩阵右移一格,加到新矩阵中。
    对于这个题来说就可以用k1的初始矩阵来乘以一个kk的递推矩阵的nk次方。
    然后矩阵快速幂就好了。
    答案是矩阵的第r个元素。
    代码:

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    ll p;
    struct matrix{
        int r,c;
        ll m[52][52];
        void init(){
            memset(m,0,sizeof(m));
        }
        inline matrix operator * (const matrix& B) const {
            matrix C;
            C.r=r;
            C.c=B.c;
            C.init();
            for(int i=0;i<r;i++){
                for(int j=0;j<B.c;j++){
                    for(int k=0;k<c;k++){
                        C.m[i][j]=(C.m[i][j]+m[i][k]*B.m[k][j])%p;
                    }
                }
            }
            return C;
        }
    };
    ll n,k,r;
    matrix ans,B;
    matrix ksm(matrix A,ll b){
        while(b){
            if(b&1){
                ans=A*ans;
            }
            A=A*A;
            b>>=1;
        }
        return ans;
    }
    int main(){
        scanf("%lld %lld %lld %lld",&n,&p,&k,&r);
        ans.init();
        ans.r=k;
        ans.c=1;
        ans.m[0][0]=1;
        B.init();
        B.r=k;
        B.c=k;
        for(int i=0;i<k;i++){
            B.m[i][i]=1;
            B.m[i][(i+1)%k]++;
        }
        ans=ksm(B,n*k);
        printf("%lld",ans.m[r][0]);
        return 0;
    }
  • 相关阅读:
    Windows 7 SP1无人值守自动应答文件制作
    Ubuntu GNOME单击任务栏图标最小化设置
    NOIP2017题解
    NOIP2017游记
    大模拟1.0
    奇袭
    礼物
    找硬币
    Fiolki
    SQLserver Delete from where 与Oracle delete from where 的差异
  • 原文地址:https://www.cnblogs.com/stone41123/p/7581265.html
Copyright © 2020-2023  润新知