Recursive sequence(HDU5950 矩阵快速幂)

题目:

Farmer John likes to play mathematics games with his N cows. Recently, they are attracted by recursive sequences. In each turn, the cows would stand in a line, while John writes two positive numbers a and b on a blackboard. And then, the cows would say their identity number one by one. The first cow says the first number a and the second says the second number b. After that, the i-th cow says the sum of twice the (i-2)-th number, the (i-1)-th number, and i4i4. Now, you need to write a program to calculate the number of the N-th cow in order to check if John’s cows can make it right.

Input:

Farmer John likes to play mathematics games with his N cows. Recently, they are attracted by recursive sequences. In each turn, the cows would stand in a line, while John writes two positive numbers a and b on a blackboard. And then, the cows would say their identity number one by one. The first cow says the first number a and the second says the second number b. After that, the i-th cow says the sum of twice the (i-2)-th number, the (i-1)-th number, and i4i4. Now, you need to write a program to calculate the number of the N-th cow in order to check if John’s cows can make it right.

Output:

For each test case, output the number of the N-th cow. This number might be very large, so you need to output it modulo 2147493647.

Hint:

In the first case, the third number is 85 = 2*1+2+3^4.In the second case, the third number is 93 = 2*1+1*10+3^4 and the fourth number is 369 = 2 * 10 + 93 + 4^4.

题意:

奶牛报数,先给两个数a和b,分别是f[n-2],f[n-1],之后每头奶牛i报数为f[i-1] + 2 * f[i-2] + i^4;给出n,求din头奶牛要报的数字,对2147493647取余。

思路:

看到这个式子知道这是一个矩阵快速幂,然后开始推式子,在我给队友写出平方差公式来队友看到杨辉三角形式后后,就去推7*7的矩阵快速幂了,但因为刚刚学这个,但结束就挂死在这个题上了。

具体式子如下:

之后就是套裸的矩阵快速幂就好了,个人感觉做题补题真的是长知识最快的方法啊。补题的时候自己直接用矩阵来写麻烦的要死,就把矩阵放在一个结构体中,顺便方便很多。

代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
typedef long long ll;
const ll MOD = 2147493647;
struct Maxt {
    ll mp[8][8];
    Maxt() {
        for(int i = 1; i<=7; i++) {
            for(int j = 1; j<=7; j++) {
                mp[i][j] = 0;
            }
        }
    }
} fp,tmp;
int n,a,b,T;
int read() {
    int res = 0;
    char op;
    op = getchar();
    if(op>=‘0‘ && op<=‘9‘) {
        res = op-‘0‘;
        op = getchar();
    }
    while(op>=‘0‘ && op<=‘9‘) {
        res = res*10 + op-‘0‘;
        op = getchar();
    }
    return res;
}

void init() {
    for(int i = 1; i<=7; i++) {
        for(int j =1; j<=7; j++) {
            fp.mp[i][j] = 0;
            tmp.mp[i][j] = 0;
        }
    }
    fp.mp[1][1] = 1,fp.mp[2][1] = 1,fp.mp[2][2] = 1,fp.mp[7][6] = 1;
    fp.mp[3][1] = 1,fp.mp[3][2] = 2,fp.mp[3][3] = 1,fp.mp[4][1] = 1;
    fp.mp[4][2] = 3,fp.mp[4][3] = 3,fp.mp[4][4] = 1,fp.mp[5][1] = 1;
    fp.mp[5][2] = 4,fp.mp[5][3] = 6,fp.mp[5][4] = 4,fp.mp[5][5] = 1;
    fp.mp[6][5] = 1,fp.mp[6][6] = 1,fp.mp[6][7] = 2;
    tmp.mp[1][1] = 1,tmp.mp[2][1] = 3,tmp.mp[3][1] = 9,tmp.mp[4][1] = 27,tmp.mp[5][1] = 81,tmp.mp[6][1] = b,tmp.mp[7][1] = a;
}

Maxt Maxtcalc(const Maxt& a,const Maxt& b) {
    Maxt t;
    for(int i = 1; i<=7; i++) {
        for(int j = 1; j<=7; j++) {
            t.mp[i][j] = 0;
            for(int k = 1; k<=7; k++) {
                t.mp[i][j] = (t.mp[i][j] + (a.mp[i][k]*b.mp[k][j]) % MOD) % MOD;
            }
        }
    }
    return t;
}

Maxt qcalc(int x,Maxt s) {
    Maxt tmp;
    for(int i = 1; i<=7; i++) {
        tmp.mp[i][i] = 1;
    }
    while(x) {
        if(x&1) {
            tmp = Maxtcalc(tmp, s);
        }
        s = Maxtcalc(s, s);
        x>>=1;
    }
    return tmp;
}

int main() {
    T = read();
    while(T--) {
        n = read();
        a = read();
        b= read();
        if(n == 1) {
            printf("%d\n",a);
            continue;
        }
        if(n == 2) {
            printf("%d\n",b);
            continue;
        }
        if(n == 3) {
            printf("%d\n",81+2*a+b);
            continue;
        }
        n = n-2;
        init();
        fp = qcalc(n,fp);
        Maxt ans =  Maxtcalc(fp, tmp);
        printf("%lld\n",ans.mp[6][1]%MOD);
    }
    return 0;
}
/*
样例输入:
2
3 1 2
4 1 10
样例输出:
85
369
*/

原文地址:https://www.cnblogs.com/sykline/p/9769878.html

时间: 2024-10-01 18:45:34

Recursive sequence(HDU5950 矩阵快速幂)的相关文章

CF1106F Lunar New Year and a Recursive Sequence(矩阵快速幂+bsgs+exgcd)

题面 传送门 前置芝士 \(BSGS\) 什么?你不会\(BSGS\)?百度啊 原根 对于素数\(p\)和自然数\(a\),如果满足\(a^x\equiv 1\pmod{p}\)的最小的\(x\)为\(p-1\),那么\(a\)就是\(p\)的一个原根 离散对数 对于素数\(p\),以及\(p\)的一个原根\(g\),定义\(y\)为\(x\)的离散对数,当且仅当\(g^y\equiv x\pmod{p}\),记\(y\)为\(ind_g x\).不难发现原数和离散对数可以一一对应.也不难发现离

HDu 5950 Recursive sequence(矩阵快速幂)

Recursive sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1323    Accepted Submission(s): 589 Problem Description Farmer John likes to play mathematics games with his N cows. Recently,

hdu 5667 Sequence【矩阵快速幂】

Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 285    Accepted Submission(s): 92 Problem Description Holion August will eat every thing he has found. Now there are many foods,but he d

A - Number Sequence(矩阵快速幂或者找周期)

Description A number sequence is defined as follows: f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. Given A, B, and n, you are to calculate the value of f(n). Input The input consists of multiple test cases. Each test case contains 3

CF - 392 C. Yet Another Number Sequence (矩阵快速幂)

CF - 392 C. Yet Another Number Sequence 题目传送门 这个题看了十几分钟直接看题解了,然后恍然大悟,发现纸笔难于描述于是乎用Tex把初始矩阵以及转移矩阵都敲了出来 \(n\le 1e17\) 这个数量级求前缀和,发现递推关系之后矩阵快速幂是可以求出来的,所以就尝试把\(A_i(k)\) 的递推式求出来. \[ A_{i-1}(k) = F_{i-1} * (i-1) ^ k\A_{i-2}(k) = F_{i-2} * (i-2) ^ k \] \[ \be

ZOJ 2105 Number Sequence(矩阵快速幂)

题意: f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. 给定A,B,求f(n). 法一: 网上较多的题解都提到了寻找1 1循环节的方法,的确非常巧妙,每位0~6,共7种可能,相邻两位共49种可能,因此循环周期至多为49,一旦出现相同数对,那么其后必相同.但是,该方法只是简单提及了49,却并没有证明1 1循环节一定存在,没有排除可能前面一段不循环,后面一段开始周期性循环的可能性.(是我悟性太差吗,为什么大多数题解都只谈

P5136 sequence(矩阵快速幂)

传送门 数列的特征方程和特征根老师上课好像讲过然而我没听--以后老师上数学课要认真听了QAQ 设\(x=\frac{1+\sqrt{5}}{2},y=\frac{1-\sqrt{5}}{2}\),那么\(x,y\)是\(t^2=t+1\)的两个解,也就是数列\(F_n=F_{n-1}+F_{n-2}\)的特征根 关于特征根是个什么神仙--可以这样理解,假设数列有\(F_n=c_1F_{n-1}+c_2F_{n-2}\),则方程的特征根\(x_1,x_2\)为\(x^2=c_1x+c_2\)的两个

[HDOJ5667]Sequence(矩阵快速幂,费马小定理)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5667 费马小定理: 假如p是质数,且gcd(a,p)=1,那么 a^(p-1)≡1(mod p). 即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1. 注意这里使用快速幂的时候要根据费马小定理对p-1取模.还有注意a%p=0的情况. 递推式:f(n)=f(n-1)*c+f(n-2)+1 非齐次. 构造矩阵: |c 1 1| |1 0 0|

HDU - 1005 Number Sequence(简单矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1005 题意:f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. 就是这道题目,然而找了一晚上的错误 \("▔□▔)/\("▔□▔)/\("▔□▔)/. 1 #include <iostream> 2 #include <cstring> 3 using namespace std;