ACM Shenyang Onsite 2016 Recursive sequence (矩阵快速幂)

题目链接

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

Input

The first line of input contains an integer ttt, the number of test cases. ttt test cases follow.

Each case contains only one line with three numbers NNN, aaa and bbb where N,a,b<231N,a,b < 2^{31}N,a,b<231 as described above.

Output

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

In the first case, the third number is 85=21+2+3485 = 21+2+3^485=21+2+34. In the second case, the third number is 93=21+1∗10+3493 = 21+1*10+3^493=21+1∗10+34 and the fourth number is 369=2∗10+93+44369 = 2 * 10 + 93 + 4^4369=2∗10+93+44.

样例输入复制

2
3 1 2
4 1 10

样例输出复制

85
369

题目要求第i个的数,他给出了f[n]=2*f[n-2]+f[n-1]+n^4;

矩阵快速幂需要的矩阵就能推出了

推矩阵时右边的一般是左边的-1,如f[n]与f[n-1]    (n+1)^4 与n^4;

然后分解左边的(n+1)^4,^3,^2,^1,依次填写就行

 

f[n]1210000f[n-1]2
f[n-1]1000000f[n-2]1
(n+1)^40014641n^481
(n+1)^30001331n^327
(n+1)^20000121n^29
(n+1)0000011n^13
1000000111
          

中间的就是快速矩阵需要的矩阵

1 2 1 0 0 0 0

1 0 0 0 0 0 0

0 0 1 4 6 4 1

0 0 0 1 3 3 1

0 0 0 0 1 2 1

0 0 0 0 0 1 1

0 0 0 0 0 0 1

矩阵出来了代码也就有了

#include<iostream>
#include<cstring>
using namespace std;
long long a1,b1;
long long mod=2147493647ll;
struct JuZ
{
    long long m[7][7];
    JuZ(){memset(m,0,sizeof(m));}
};
JuZ f(JuZ a,JuZ b)
{
    JuZ c;
    for(int i=0;i<7;i++)
    {
        for(int j=0;j<7;j++)
        {
            for(int k=0;k<7;k++)
                c.m[i][j]=(a.m[i][k]*b.m[k][j]+c.m[i][j])%mod;
        }
    }
    return c;
}

void solv(int n)
{
    JuZ a;
    JuZ b;
    for(int i=0;i<7;i++)b.m[i][i]=1;
    a.m[0][0]=1;a.m[0][1]=2;a.m[0][2]=1;a.m[1][0]=1;a.m[2][2]=1;
    a.m[2][3]=4;a.m[2][4]=6;a.m[2][5]=4;a.m[2][6]=1;a.m[3][3]=1;
    a.m[3][4]=3;a.m[3][5]=3;a.m[3][6]=1;a.m[4][4]=1;a.m[4][5]=2;
    a.m[4][6]=1;a.m[5][5]=1;a.m[5][6]=1;a.m[6][6]=1;
    while(n>0)
    {
        if(n&1)b=f(a,b);
        a=f(a,a);
        n>>=1;
    }
   /* for(int i=0;i<7;i++)
        cout<<b.m[0][i]<<endl;*/
   long long sum=(b.m[0][0]*b1%mod+b.m[0][1]*a1%mod+b.m[0][2]*81%mod)%mod;
  // cout<<b.m[0][1]*a1<<endl;
    sum=(b.m[0][3]*27%mod+b.m[0][4]*9%mod+b.m[0][5]*3%mod+b.m[0][6]+sum)%mod;
    cout<<sum<<endl;
}

int main()
{
    int t;
    cin>>t;
    while(t--){
            int n;
    cin>>n>>a1>>b1;
        if(n>2)solv(n-2);
        else if(n==1)cout<<a1<<endl;
        else cout<<b1<<endl;
    }
    return 0;
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值