hdu 5950 Recursive sequence

  题意:告诉你数列的递推公式为f(n+1)=f(n)+2*f(n-1)+(n+1)^4 以及前两项a,b;问第n项为多少,结果对2147493647取模。

  题解:有递推公式,马上应该就能想到矩阵快速幂;但是,以前写过的矩阵快速幂绝大都是常数做系数的,如果这题是f(n+1)=f(n)+2*f(n-1)这样那倒蛮简单的构造个2*2矩阵很快能做出来;而后面接个(n+1)^4这种当时就gg了,,不知该如何下手。后来拜读了大佬的代码后才恍然大悟,,=_=...

  对于(n+1)^4,展开来后就是n^4+4*n^3+6*n^2+4*n+1,以及(n+1)^3展开是n^3+3*n^2+3*n+1那么,根据这个公式就可以在矩阵相乘时由{f(n),f(n-1),n^4,n^3,n^2,n,1}递推出{f(n+1),f(n),(n+1)^4,(n+1)^3,(n+1)^2,(n+1),1}。  故可构造7*7矩阵:

                                                          

     用矩阵快速幂求其n-2次方的结果后,再与矩阵{ f(2), f(1), 2^4, 2^3, 2^2, 2, 1 } 即可得到第n项。

ac代码:

复制代码
 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <set>
 7 #include <utility>
 8 #include <vector>
 9 #include <map>
10 #include <queue>
11 #include <stack>
12 const int inf=0x3f3f3f3f;
13 const double PI=acos(-1.0);
14 const double EPS=1e-8;
15 using namespace std;
16 typedef long long ll;
17 typedef pair<int,int> P;
18 
19 const ll mod=2147493647LL;
20 ll n,a,b;
21 typedef struct Marix
22 {
23     ll m[7][7];
24 } Marix;
25 Marix p = {1, 1, 0, 0, 0, 0, 0,
26            2, 0, 0, 0, 0, 0, 0,
27            1, 0, 1, 0, 0, 0, 0,
28            4, 0, 4, 1, 0, 0, 0,
29            6, 0, 6, 3, 1, 0, 0,
30            4, 0, 4, 3, 2, 1, 0,
31            1, 0, 1, 1, 1, 1, 1
32           };
33 Marix mul(Marix a,Marix b)
34 {
35     Marix c;
36     memset(c.m,0,sizeof(c.m));
37     for(int k=0; k<7; k++)
38         for(int i=0; i<7; i++)
39             for(int j=0; j<7; j++)
40                 c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j]%mod)%mod;
41     return c;
42 }
43 Marix pow_mod(Marix a,ll n)
44 {
45     Marix c;
46     for(int i=0; i<7; i++) for(int j=0; j<7; j++) c.m[i][j]=(i==j); //将c初始化为单位矩阵
47     //
48     for(; n; n>>=1)
49     {
50         if(n&1) c=mul(c,a);
51         a=mul(a,a);
52     }
53     return c;
54 }
55 void debug()
56 {
57 }
58 int main()
59 {
60     //freopen("input.txt","r",stdin);
61     //debug();
62     int T;
63     scanf("%d",&T);
64     while(T--)
65     {
66         scanf("%I64d%I64d%I64d",&n,&a,&b);
67         //
68         if(n==1)
69         {
70             cout<<a<<endl;
71             continue;
72         }
73         else if(n==2)
74         {
75             cout<<b<<endl;
76             continue;
77         }
78         //
79         Marix c=pow_mod(p,n-2);
80         ll ans=b*c.m[0][0]%mod+a*c.m[1][0]%mod;
81         ans+=16*c.m[2][0]+8*c.m[3][0]+4*c.m[4][0]+2*c.m[5][0]+c.m[6][0];
82         cout<<ans%mod<<endl;
83     }
84     return 0;
85 }
复制代码

 

posted @   爱喝可乐的咖啡  阅读(182)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示