zoukankan      html  css  js  c++  java
  • bzoj2326: [HNOI2011]数学作业

    矩阵乘法.

                                          10^k,0,0

    (f[i+1],i+1,1) = (f[i],i,1)  ( 1,     1,0 )

                                           1.     1,0)

    k为(i+1)的位数。这点很重要,所以每回都是算到999…9,然后k就会+1。所以题目中的l和r都是实际值+1。(需要yy一下)。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    unsigned long long n,mod;
    
    struct Matrix {
        long long a[3][3];
        
        long long* operator [] (int x) {
            return a[x];
        }
        
        Matrix operator* (Matrix b) {
            Matrix res;
            for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
            for(int k=0;k<3;k++)
            res[i][j]=(res[i][j]+a[i][k]*b[k][j])%mod;
            return res;    
        }
        
        Matrix operator ^ (long long e) {
            Matrix res(1),tmp=*this;
            while(e) {
                if(e&1) res=res*tmp;
                tmp=tmp*tmp;
                e>>=1;
            }
            return res;
        }
        
        void build(long long x) {
            memset(a,0,sizeof(a));
            a[0][0]=x%mod;
            for(int i=1;i<3;i++)
            for(int j=0;j<=i;j++)
                a[i][j]=1;
        }
        
        Matrix(long long x=0) {
            memset(a,0,sizeof(a));
            for(int i=0;i<3;i++) a[i][i]=x;    
        }
        
    }cur;
    
    struct Vector {
        long long a[3];    
        
        long long& operator [] (int x) {
            return a[x];
        }
        
        Vector operator * (Matrix b) {
            Vector res;
            for(int i=0;i<3;i++) 
            for(int k=0;k<3;k++) 
                res[i]=(res[i]+a[k]*b[k][i])%mod;
            return res;
        }
        
        void build() {
            memset(a,0,sizeof(a));    
            a[2]=1;
        }
        
        Vector() {
            memset(a,0,sizeof(a));
        }
    }res;
    
    int main() {
        scanf("%lld%lld",&n,&mod);
        res.build();
        long long l,r;
        for(l=1,r=10;r<=n;l=r,r=l*10) {
            cur.build(r);
            res=res*(cur^(r-l));
        }
        cur.build(r);
        res=res*(cur^(n-l+1));
        printf("%lld
    ",res[0]);
        return 0;
    }
  • 相关阅读:
    npm改为淘宝镜像
    html中table中td内容换行
    git 切换文件夹路径
    git经常使用的命令
    day16
    day15
    day13
    day14
    day12
    day11
  • 原文地址:https://www.cnblogs.com/invoid/p/5526081.html
Copyright © 2011-2022 走看看