D: Starry的神奇魔法(矩阵快速幂)

题目链接:https://oj.ismdeep.com/contest/Problem?id=1284&pid=3

D: Starry的神奇魔法

Time Limit: 1 s      Memory Limit: 128 MB

Submit My Status

Problem Description

啦啦啦,Starry正愉快的做着编程题,代码是多么优美呀!突然,有人问他一道数学题,对于数学渣渣的Starry来说,这是多么的烦恼呀。不过不要紧,他还可以问其他人的,所以他想到了聪明的你们。这个问题是由一个神奇的魔法师提出的,他创造了一种魔法,每次使用魔法可以让今天的魔力值为前一天魔力值的2018倍+前两天魔力值的8倍+前三天魔力值的12倍。当然,一天只能使用一次魔法,除了使用魔法外,每天魔法师还能产生8888的魔力值。第一、二、三天的初始魔力值为888。他想问的是第n天他可以拥有多少魔力值。

Input

第一行输入一个T表示有TT个问题(1≤T≤104)(1≤T≤104)。

接下来T行,每行有一个数n(1≤n≤1018)n(1≤n≤1018),表示第nn天。

Output

输出TT行,每行输出第nn天的魔力值,由于数很大,结果对2018081220180812取模。

Sample Input

3
2
5
8

Sample Output

888
17299052
16854116

题目大意:f[1]=f[2]=f[3]=888;给出任意n(1<=n<=10^18),求f(n) = 2018*f(n-1)+8*f(n-2)+12*f(n-3)+8888。

解题思路:由递推公式我们可以得到以下矩阵:

通过递推可得到矩阵:

当n<=3时,直接输出888;

而当n>3时,直接计算上述矩阵式,先求出第一个矩阵的n-3次方,然后只要用第一个矩阵的第一行与第二个矩阵的第一列对应相乘相加即可得到答案。

附上代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
const int mod=20180812;
const int maxn=4;
typedef long long ll;
struct Matrix{
    ll a[maxn][maxn];
};

Matrix mul(Matrix a,Matrix b)  //两矩阵相乘
{
    Matrix temp;
    memset(temp.a,0,sizeof(temp.a));
    for(int i=0;i<maxn;i++)
        for(int j=0;j<maxn;j++)
            for(int k=0;k<maxn;k++)
                temp.a[i][j]=(temp.a[i][j]+a.a[i][k]*b.a[k][j])%mod;
    return temp;
}

Matrix qpow(Matrix a,ll n)  //矩阵快速幂
{
    Matrix ans;
    memset(ans.a,0,sizeof(ans.a));
    for(int i=0;i<maxn;i++)
        ans.a[i][i]=1; //化成单位矩阵
    while(n)
    {
        if(n&1) ans=mul(ans,a);
        a=mul(a,a);
        n/=2;
    }
    return ans;
}

int main()
{
    int t;
    scanf("%d",&t);
    Matrix A;
    A.a[0][0]=2018,A.a[0][1]=8,A.a[0][2]=12,A.a[0][3]=1;
    A.a[1][0]=1,A.a[1][1]=0,A.a[1][2]=0,A.a[1][3]=0;
    A.a[2][0]=0,A.a[2][1]=1,A.a[2][2]=0,A.a[2][3]=0;
    A.a[3][0]=0,A.a[3][1]=0,A.a[3][2]=0,A.a[3][3]=1;
    while(t--)
    {
        ll n;
        scanf("%lld",&n);
        if(n<=3)
        {
            printf("888\n");
            continue;
        }
        Matrix x=qpow(A,n-3);
        ll ans=x.a[0][0]*888+x.a[0][1]*888+x.a[0][2]*888+x.a[0][3]*8888;
        printf("%lld\n",ans%mod);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/zjl192628928/p/9536402.html

时间: 2024-08-06 13:04:37

D: Starry的神奇魔法(矩阵快速幂)的相关文章

hdu5171(矩阵快速幂)

传送门:GTY's birthday gift 题意:GTY的朋友ZZF的生日要来了,GTY问他的基友送什么礼物比较好,他的一个基友说送一个可重集吧!于是GTY找到了一个可重集S,GTY能使用神犇魔法k次,每次可以向可重集中加入一个数 a+b(a,b∈S),现在GTY想最大化可重集的和,这个工作就交给你了. 注:可重集是指可以包含多个相同元素的集合 分析:想要和最大,那么每次必定从集合里面拿出最大的两个出来相加,然后k次后面就类似斐波那契数列了. 由斐波那契数列公式知:Fn=Fn-1+Fn-2,

BestCoder Round #29——A--GTY&#39;s math problem(快速幂(对数法))、B--GTY&#39;s birthday gift(矩阵快速幂)

GTY's math problem Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 0    Accepted Submission(s): 0 Problem Description GTY is a GodBull who will get an Au in NOI . To have more time to learn alg

残(矩阵快速幂)

定义f(x)为斐波那契数列第x项 输出f(f(x))%1000000007: x<=10^100; 思路: 矩阵快速幂+各种神奇的模: 来,上代码: #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define mod 1000000007LL #define mod2 2000000016LL #

hdu4990矩阵快速幂

就是优化一段代码,用矩阵快速幂(刚开始想到了转移矩阵以为是错的) 在搜题解时发现了一个神奇的网站:http://oeis.org/ 用来找数列规律 的神器.... 规律就是an=an-1+2*an-2+1 然后构造矩阵就行了 还有特例1的时候记得%m #include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector>

GTY&#39;s birthday gift【矩阵快速幂】

题目大意:GTY的朋友ZZF的生日要来了,GTY问他的基友送什么礼物比较好,他的一个基友说送一个可重集吧!于是GTY找到了一个可重集S,GTY能使用神犇魔法k次,每次可以向可重集中加入一个数 a+b ,现在GTY想最大化可重集的和,这个工作就交给你了. 注:可重集是指可以包含多个相同元素的集合 思路:这题 呵呵呵,太伤心 不想写思路 #include<iostream>#include<cstdio>#include <math.h>#include<algori

矩阵快速幂(入门) 学习笔记hdu1005, hdu1575, hdu1757

矩阵快速幂是基于普通的快速幂的一种扩展,如果不知道的快速幂的请参见http://www.cnblogs.com/Howe-Young/p/4097277.html.二进制这个东西太神奇了,好多优秀的算法都跟他有关系,这里所说的矩阵快速幂就是把原来普通快速幂的数换成了矩阵而已,只不过重载了一下运算符*就可以了,也就是矩阵的乘法,  当然也可以写成函数,标题中的这三个题都是关于矩阵快速幂的基础题.拿来练习练习熟悉矩阵快速幂,然后再做比较难点的,其实矩阵快速幂比较难的是构造矩阵.下面还是那题目直接说话

[BZOJ3583]杰杰的女性朋友(矩阵快速幂)

杰杰的女性朋友 时间限制:10s      空间限制:256MB 题目描述 杰杰是魔法界的一名传奇人物.他对魔法具有深刻的洞察力,惊人的领悟力,以及令人叹为观止的创造力.自从他从事魔法竞赛以来,短短几年时间,就已经成为 世界公认的实力最强的魔法选手之一.更让人惊叹的是,他几乎没有借助外界力量,完全凭借自己的努力达到了普通人难以企及的高度.在最近的世界魔法奥林匹克 竞赛上,他使用高超的魔法本领,一路过关斩将,在最后时刻一举击败了前冠军"旅行者",获得了魔法界最高的荣耀:女神奖杯!女神奖杯

矩阵乘法&amp;&amp;矩阵快速幂&amp;&amp;最基本的矩阵模型——斐波那契数列

矩阵,一个神奇又令人崩溃的东西,常常用来优化序列递推 在百度百科中,矩阵的定义: 在数学中,矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合 ,最早来自于方程组的系数及常数所构成的方阵.这一概念由19世纪英国数学家凯利首先提出. 好,很高深对吧.那我们就更加直接地理解一下矩阵的实质:二维数组 好了这个SB都会,就不解释了 同二维数组一样,矩阵是一个'纵横排列的二维数据表格',它一般是一个n*m的二维数组,其中n*m表示它有n行m列 每一位上的数可以用下标i,j来表示,形如这样一个矩阵:

eduCF#60 D. Magic Gems /// 矩阵快速幂

题目大意: 给定n m (1≤N≤1e18, 2≤M≤100) 一个魔法水晶可以分裂成连续的m个普通水晶 求用水晶放慢n个位置的方案modulo 1000000007 (1e9+7) input 4 2 output 5 设1为魔法水晶 0为普通水晶 n=4 m=2有5种方案 即 1111.0011.1001.1100.0000 得到递推公式 当 i < m 时 dp[ i ] = 1 当 i >= m 时 dp[ i ] = dp[ i-1 ] + dp[ i-m ] n的范围是1e18 构