• 西南民大oj(矩阵快速幂)


    我的名字不可能那么难记

    时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
    总提交 : 16            测试通过 : 9 

    描述

     

    Nirvava:Hi,Misaki,听说ZC要离开了..

     

    Misaki:好走不送,祝一帆风顺

     

    Nirvana: 但他留了好多doge给我们

     

    Misaki:……

     

    Nirvana:而且他们还有名字,名字如下。

     

     

     

    据说ZC离去的原因之一就是因为第Ndoge老是问他能不能记住它的名字。

     

    Misaki:记别人名字什么的,好烦哒,ZC肯定记不住。

     

    Nirvana:ZC当然记得,毕竟是他的宠物嘛。难倒他的是,doge的第二个问题:我的名字有多长ZC难住了,因为他数着数着就doge精神污染了。

     

    Misaki:这个问题,,真的好难..不过,,他们应该能解决。

     

    PS:这个题面是不是有点熟♂悉,懒得想题面了,就把以前的题面拿出来了。

    输入

     

    多组输入

    每组一个N(0<N<=10^9)

    输出

    第N个doge的名字有多长,由于可能太长,你只需要输出长度%1000000007(1e9+7)的结果即可。

    样例输入

    1
    2
    3
    4
    500

    样例输出

    1
    3
    7
    17
    875025602

    提示

     

    name[1]="X"
    name[2]="XXY"
    name[3]="XXYXXYX"
    name[4]="XXYXXYXXXYXXYXXXY"
    ……
    以此类推。
    分析:设a[i]为总长度,b[i]为X的个数,c[i]为Y的个数,则有a[i]=3*b[i-1]+c[i-1],b[i]=2*b[i-1]+c[i-1],c[i]=b[i-1].
    则可构造矩阵
                                    |0,0,0|
    |a[i-1] ,b[i-1],c[i-1]|*|3,2,1|=|a[i],b[i],c[i]|
                                    |1,1,0|
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define N 1000010
    using namespace std;
    struct matrix
    {
        LL m[3][3];
    };
    LL n;
    matrix mult(matrix a,matrix b)
    {
        matrix c;
        memset(c.m,0,sizeof(c.m));
        for(int i=0;i<3;i++)
        for(int k=0;k<3;k++)
        {
            if(a.m[i][k]==0)continue;
            for(int j=0;j<3;j++)
            {
                if(b.m[k][j]==0)continue;
                c.m[i][j]+=a.m[i][k]*b.m[k][j]%mod;
                c.m[i][j]%=mod;
            }
        }
        return c;
    }
    matrix quickmod(matrix a,LL n)
    {
        matrix temp;
        memset(temp.m,0,sizeof(temp.m));
        for(int i=0;i<3;i++)temp.m[i][i]=1;
        while(n)
        {
            if(n&1)temp=mult(temp,a);
            a=mult(a,a);
            n>>=1;
        }
        return temp;
    }
    
    int main()
    {
        while(scanf("%lld",&n)!=EOF)
        {
            if(n==1){puts("1");continue;}
            matrix ans;
            memset(ans.m,0,sizeof(ans.m));
            ans.m[0][0]=0;ans.m[0][1]=0;ans.m[0][2]=0;
            ans.m[1][0]=3;ans.m[1][1]=2;ans.m[1][2]=1;
            ans.m[2][0]=1;ans.m[2][1]=1;ans.m[2][2]=0;
            ans=quickmod(ans,n-1);
            printf("%lld
    ",ans.m[1][0]);
        }
    }
    View Code
     
  • 相关阅读:
    SQL中常用的数据类型及简介
    静态方法与非静态方法
    遍历多维数组
    遍历一个三维数组
    冒泡排序-方法2
    关于二分查找分
    冒泡排列-——方法1
    AngularJS 循环查询数组
    AngularJs 指令
    给定一个年月值,返回上个年月值,格式为:YYYY.MM string类型
  • 原文地址:https://www.cnblogs.com/lienus/p/4189904.html
Copyright © 2020-2023  润新知