HDU 5950 - Recursive sequence - [矩阵快速幂加速递推][2016ACM/ICPC亚洲区沈阳站 Problem C]

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5950

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 $i^4$. 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
The first line of input contains an integer t, the number of test cases. t test cases follow. 
Each case contains only one line with three numbers N, a and b where $N,a,b < 2^31$ as described above.

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$.

Sample Input
2
3 1 2
4 1 10

Sample Output
85
369

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

题意:

给出 $a,b,n$,已知 $a_1 = a, a_2 = b$,且对于 $i>2$ 的 $a_i = 2a_{i-2} + a_{i-1} + i^4$,求 $a_n$。

题解:

看一眼 $n$ 最大在 $2e9$,显然不是暴力的递推。考虑矩阵快速幂加速递推。

不妨设一个矩阵

那么就有

我们只要求出一个矩阵 $A$,使其满足 $F(n+1) = F(n) \times A$,就能进行矩阵快速幂加速递推。

根据二项式定理很容易得到

因此不难就求得满足 $F(n+1) = F(n) \times A$ 矩阵 $A$ 如下:

此时,对于任意的 $F(n)$,都可以由 $F(n) = F(2) \times A^{n-2}$ 求得,$A^{n-2}$ 用矩阵快速幂可以 $O(\log n)$ 求出。

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=2147493647;

const int DIM=7;
struct Matrix
{
    ll mat[DIM][DIM];
    Matrix operator*(Matrix const &oth)const
    {
        Matrix res;
        memset(res.mat,0,sizeof(res.mat));
        for(int i=0;i<DIM;i++)
            for(int j=0;j<DIM;j++)
                for(int k=0;k<DIM;k++)
                    res.mat[i][j]+=(mat[i][k]*oth.mat[k][j])%mod,
                    res.mat[i][j]%=mod;
        return res;
    }
}A,F2,Fn;
Matrix fpow(Matrix base,ll n)
{
    Matrix res;
    memset(res.mat,0,sizeof(res.mat));
    for(int i=0;i<DIM;i++) res.mat[i][i]=1;
    while(n)
    {
        if(n&1) res=res*base;
        base=base*base;
        n>>=1;
    }
    return res;
}

void initA()
{
    A.mat[0][0]=0, A.mat[0][1]=2, A.mat[0][2]=0, A.mat[0][3]=0, A.mat[0][4]=0, A.mat[0][5]=0, A.mat[0][6]=0;
    A.mat[1][0]=1, A.mat[1][1]=1, A.mat[1][2]=0, A.mat[1][3]=0, A.mat[1][4]=0, A.mat[1][5]=0, A.mat[1][6]=0;
    A.mat[2][0]=0, A.mat[2][1]=1, A.mat[2][2]=1, A.mat[2][3]=0, A.mat[2][4]=0, A.mat[2][5]=0, A.mat[2][6]=0;
    A.mat[3][0]=0, A.mat[3][1]=0, A.mat[3][2]=4, A.mat[3][3]=1, A.mat[3][4]=0, A.mat[3][5]=0, A.mat[3][6]=0;
    A.mat[4][0]=0, A.mat[4][1]=0, A.mat[4][2]=6, A.mat[4][3]=3, A.mat[4][4]=1, A.mat[4][5]=0, A.mat[4][6]=0;
    A.mat[5][0]=0, A.mat[5][1]=0, A.mat[5][2]=4, A.mat[5][3]=3, A.mat[5][4]=2, A.mat[5][5]=1, A.mat[5][6]=0;
    A.mat[6][0]=0, A.mat[6][1]=0, A.mat[6][2]=1, A.mat[6][3]=1, A.mat[6][4]=1, A.mat[6][5]=1, A.mat[6][6]=1;
}

ll n,a,b;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    initA();
    int T;
    cin>>T;
    while(T--)
    {
        cin>>n>>a>>b;
        if(n==1) {
            cout<<a<<‘\n‘;
            continue;
        }
        if(n==2) {
            cout<<b<<‘\n‘;
            continue;
        }

        memset(F2.mat,0,sizeof(F2.mat));
        memset(Fn.mat,0,sizeof(Fn.mat));

        F2.mat[0][0]=a, F2.mat[0][1]=b,
        F2.mat[0][2]=3*3*3*3, F2.mat[0][3]=3*3*3, F2.mat[0][4]=3*3, F2.mat[0][5]=3, F2.mat[0][6]=1;

        Fn=F2*fpow(A,n-2);
        cout<<Fn.mat[0][1]<<‘\n‘;
    }
}

原文地址:https://www.cnblogs.com/dilthey/p/9945679.html

时间: 2024-11-05 16:02:22

HDU 5950 - Recursive sequence - [矩阵快速幂加速递推][2016ACM/ICPC亚洲区沈阳站 Problem C]的相关文章

HDU 5950 Recursive sequence 矩阵快速幂

http://acm.hdu.edu.cn/showproblem.php?pid=5950 一开始以为i^4不能矩阵快速幂,但是结论是可以得,那么要怎么递推呢? 矩阵快速幂的思路都是一样的,matrix_a * matrix_b ^ n 其中,想要维护什么,就在matrix_a写,比如现在是F[n - 1], F[n - 2],我想要递推到下一项,那么就 会变成F[n], F[n - 1],这个时候,你就要寻找一下F[n]和F[n - 1]有什么关系. i^4也一样,想要从i^4 递推到 (i

5950 Recursive sequence (矩阵快速幂)

题意:递推公式 Fn = Fn-1 + 2 * Fn-2 + n*n,让求 Fn; 析:很明显的矩阵快速幂,因为这个很像Fibonacci数列,所以我们考虑是矩阵,然后我们进行推公式,因为这样我们是无法进行运算的.好像有的思路,最后也没想出来,还是参考的大牛的博客 http://blog.csdn.net/spring371327/article/details/52973534 那是讲的很详细了,就不多说了,注意这个取模不是1e9+7,一开始忘了.. 代码如下: #pragma comment

POJ3070 Fibonacci(矩阵快速幂加速递推)【模板题】

题目链接:传送门 题目大意: 求斐波那契数列第n项F(n). (F(0) = 0, F(1) = 1, 0 ≤ n ≤ 109) 思路: 用矩阵乘法加速递推. 算法竞赛进阶指南的模板: #include <iostream> #include <cstring> using namespace std; const int MOD = 10000; void mul(int f[2], int base[2][2]) { int c[2]; memset(c, 0, sizeof

HDU 5954 - Do not pour out - [积分+二分][2016ACM/ICPC亚洲区沈阳站 Problem G]

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5954 Problem DescriptionYou have got a cylindrical cup. Its bottom diameter is 2 units and its height is 2 units as well.The height of liquid level in the cup is d (0 ≤ d ≤ 2). When you incline the cup t

HDU 5950 Recursive sequence 【递推+矩阵快速幂】 (2016ACM/ICPC亚洲区沈阳站)

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

HDU 1005 Number Sequence 矩阵快速幂

Number Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 236241    Accepted Submission(s): 60070 Problem Description A number sequence is defined as follows: f(1) = 1, f(2) = 1, f(n) = (A

CF1106F Lunar New Year and a Recursive Sequence——矩阵快速幂&amp;&amp;bsgs

题意 设 $$f_i = \left\{\begin{matrix}1 , \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  i < k\\ \prod_{j=1}^k f_{i-j}^{b_j} \ mod \ p, \ \ \ \ \ i > k\end{matrix}\right.$$ 求 $f_k$($1 \leq f_k < p$),使得 $f_m = n$.($1 \leq k\leq 100$) 分析 $f_n$ 可以表示

ZOJ 3690 &amp; HDU 3658 (矩阵快速幂+公式递推)

ZOJ 3690 题意: 有n个人和m个数和一个k,现在每个人可以选择一个数,如果相邻的两个人选择相同的数,那么这个数要大于k 求选择方案数. 思路: 打表推了很久的公式都没推出来什么可行解,好不容易有了想法结果WA到天荒地老也无法AC.. 于是学习了下正规的做法,恍然大悟. 这道题应该用递推 + 矩阵快速幂. 我们设F(n) = 有n个人,第n个人选择的数大于k的方案数: G(n) = 有n个人,第n个人选择的数小于等于k的方案数: 那么递推关系式即是: F(1)=m?k,G(1)=k F(n

矩阵快速幂优化递推总结

RT,主要总结一下矩阵的求法. 首先能用矩阵快速幂优化的递推类型是f[n]=5f[n-3]+6f[n-2]+2f[n-1]+n^2+n+8之类的 也就是说递推是线性递推且f[n-i]前面的系数是常数,可以含有与n有关的多项式,也可以含有常数的这种递推,下面总结一下矩阵的写法: 先考虑最简单的常数,我们其实可以忽略常数,因为顶多在没有常数的矩阵外面加一行一列就行了 以f[n]=2f[n-1]+6f[n-2]+5f[n-3]+n^2+n为例 先写迭代的矩阵,一般可以写成一行,右边有几项写几项 {f[