【HDOJ5950】Recursive sequence(矩阵乘法,快速幂)

题意:f[1]=a,f[2]=b,f[i]=2f[i-2]+f[i-1]+i^4(i>=3),多组询问求f[n]对2147493647取模

N,a,b < 2^31

思路:重点在于i^4的处理

对于i转移矩阵中可以记录下它的0,1,2,3,4次项

i的幂又可以由i-1的幂运算得出,最后推出的系数是二项式展开的系数

试试新的矩乘模板

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<string>
  4 #include<cmath>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<map>
  8 #include<set>
  9 #include<queue>
 10 #include<vector>
 11 using namespace std;
 12 typedef long long ll;
 13 typedef unsigned int uint;
 14 typedef unsigned long long ull;
 15 typedef pair<int,int> PII;
 16 typedef vector<int> VI;
 17 #define fi first
 18 #define se second
 19 #define MP make_pair
 20 #define N   2100000
 21 #define MOD 2147493647
 22 #define eps 1e-8
 23 #define pi acos(-1)
 24 const int MAXN=10;
 25
 26 int read()
 27 {
 28    int v=0,f=1;
 29    char c=getchar();
 30    while(c<48||57<c) {if(c==‘-‘) f=-1; c=getchar();}
 31    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 32    return v*f;
 33 }
 34
 35
 36 struct matrix       //矩阵类
 37 {
 38     int n,m;
 39     ll data[MAXN][MAXN];
 40 };
 41
 42 matrix ma,mb;
 43 ll a,b,c,d,p,n;
 44
 45 matrix matrixMul(matrix a, matrix b)
 46 {
 47     matrix re;
 48     if(a.m!=b.n)
 49     {
 50         printf("error\n");
 51         return re;
 52     }
 53     memset(re.data,0,sizeof(re.data));
 54     re.n = a.n; re.m = b.m;
 55     for(int i = 1; i <= a.n; i++)
 56     {
 57         for(int j = 1; j <= a.m; j++)
 58         {
 59             if(a.data[i][j] == 0) continue;
 60             for(int k = 1; k <= b.m; k++)
 61             {
 62                 re.data[i][k] += (a.data[i][j] % MOD * b.data[j][k] % MOD) % MOD;
 63                 re.data[i][k] %= MOD;
 64             }
 65         }
 66     }
 67     return re;
 68 }
 69
 70 matrix matrixPow(matrix a,int b)
 71 {
 72     matrix re;
 73     if(a.n!=a.m)
 74     {
 75         printf("error2\n");
 76         return re;
 77     }
 78     re.n=re.m=a.n;
 79     memset(re.data,0,sizeof(re.data));
 80     for(int i=1;i<=re.n;i++) re.data[i][i]=1;
 81     while(b)
 82     {
 83         if(b&1) re=matrixMul(re,a);
 84         a=matrixMul(a,a);
 85         b>>=1;
 86     }
 87     return re;
 88 }
 89
 90 void inputMat(int n,int m,matrix &a,ll *b)
 91 {
 92     a.n = n; a.m = m;
 93     for(int i = 1; i <= n; i++)
 94         for(int j = 1; j <= m; j++)
 95             a.data[i][j] = *(b + (i - 1) * m + (j - 1));
 96 }
 97
 98 void init(){
 99     ll pt[1][7] = {b,a,16,8,4,2,1};
100     inputMat(1,7,ma,*pt);
101     ll pt2[7][7] = {1,1,0,0,0,0,0,
102                     2,0,0,0,0,0,0,
103                     1,0,1,0,0,0,0,
104                     4,0,4,1,0,0,0,
105                     6,0,6,3,1,0,0,
106                     4,0,4,3,2,1,0,
107                     1,0,1,1,1,1,1,};
108     inputMat(7,7,mb,*pt2);
109 }
110
111 int main()
112 {
113     int cas;
114     scanf("%d",&cas);
115     while(cas--)
116     {
117         scanf("%I64d%I64d%I64d",&n,&a,&b);
118         int i=3;
119         a%=MOD;
120         b%=MOD;
121         if(n == 1)
122             printf("%I64d\n",a);
123         else if(n == 2)
124             printf("%I64d\n",b);
125         else
126         {
127
128                 init();
129                 ma=matrixMul(ma,matrixPow(mb,n-2));
130         }
131         printf("%I64d\n",ma.data[1][1]);
132     }
133     return 0;
134 }

原文地址:https://www.cnblogs.com/myx12345/p/9742139.html

时间: 2024-10-11 09:13:39

【HDOJ5950】Recursive sequence(矩阵乘法,快速幂)的相关文章

快速求斐波那契数列(矩阵乘法+快速幂)

斐波那契数列 给你一个n:f(n)=f(n-1)+f(n-2) 请求出 f(f(n)),由于结果很大请 对答案 mod 10^9+7; 1<=n<=10^100; 用矩阵乘法+快速幂求斐波那契数列是经典应用: 矩阵公式 C i j=C i k *C k j; 根据递推式 构造2*2矩阵: 原始矩阵 1 0 0 1 矩阵 2 1 1 1 0 原始矩阵与矩阵 2相乘达到转化状态效果: 对矩阵二进行快速幂 乘法:达到快速转化矩阵的效果: 即使达到快速转化状态:那么大的数据范围也很难求解: 高精?这有

HDU 4914 Linear recursive sequence(矩阵乘法递推的优化)

题解见X姐的论文 矩阵乘法递推的优化,只是mark一下.. HDU 4914 Linear recursive sequence(矩阵乘法递推的优化)

codevs1281 矩阵乘法 快速幂 !!!手写乘法取模!!! 练习struct的构造函数和成员函数

对于这道题目以及我的快速幂以及我的一节半晚自习我表示无力吐槽,, 首先矩阵乘法和快速幂没必要太多说吧,,嗯没必要,,我相信没必要,,实在做不出来写两个矩阵手推一下也就能理解矩阵的顺序了,要格外注意一些细节,比如快速幂时ans矩阵的初始化方式,快速幂的次数,矩阵乘法过程中对临时矩阵的清零,最后输出结果时的初始矩阵...矩阵快速幂好理解但是细节还是有点小坑的.. 下面就是满满的槽点,,高能慎入!!! 对于这个题目要求矩阵过程中对m取模,结果对g取模,我表示难以接受,,上来没看清题直接wa19个点,另

矩阵乘法快速幂 codevs 1732 Fibonacci数列 2

1732 Fibonacci数列 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 在“1250 Fibonacci数列”中,我们求出了第n个Fibonacci数列的值.但是1250中,n<=109.现在,你的任务仍然是求出第n个Fibonacci数列的值,但是注意:n为整数,且1 <= n <= 100000000000000 输入描述 Input Description 输入有多组数据,每

【BZOJ 2323】 2323: [ZJOI2011]细胞 (DP+矩阵乘法+快速幂*)

2323: [ZJOI2011]细胞 Description 2222年,人类在银河系外的某颗星球上发现了生命,并且携带了一个细胞回到了地球.经过反复研究,人类已经完全掌握了这类细胞的发展规律: 这种细胞最初的形态是"长条形",一端是头,一端是尾,中间是躯干.细胞内部含有一列密码(你可以认为它是这种细胞的DNA).密码是一个长度为n的数字串,且仅含有1~9这9种数字,沿着细胞的躯干从头到尾排列着. 首先,细胞会经历一次分裂.细胞将沿躯干方向分裂成若干个球体,躯干将退化成丝状物,连接着相

【bzoj3231】[Sdoi2008]递归数列 矩阵乘法+快速幂

题目描述 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai-k 其中bj和 cj (1<=j<=k)是给定的自然数.写一个程序,给定自然数m <= n, 计算am + am+1 + am+2 + ... + an, 并输出它除以给定自然数p的余数的值. 输入 由四行组成. 第一行是一个自然数k. 第二行包含k个自然数b1, b2,...,bk. 第三行包含k个自然数c1,

矩阵乘法快速幂 codevs 1574 广义斐波那契数列

codevs 1574 广义斐波那契数列 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 广义的斐波那契数列是指形如an=p*an-1+q*an-2的数列.今给定数列的两系数p和q,以及数列的最前两项a1和a2,另给出两个整数n和m,试求数列的第n项an除以m的余数. 输入描述 Input Description 输入包含一行6个整数.依次是p,q,a1,a2,n,m,其中在p,q,a1,a2整数范围内,n和m在长整数范围

【BZOJ-1009】GT考试 KMP+DP+矩阵乘法+快速幂

1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2745  Solved: 1694[Submit][Status][Discuss] Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2..

【bzoj4887】:[Tjoi2017]可乐 矩阵乘法,快速幂

[bzoj4887]:[Tjoi2017]可乐 题目大意:一张无相连通图(n<=30),从1号点开始走,每秒可以走到相邻的点也可以自爆,求第t秒(t<=1e6)后所有的方案数是多少对2017取模 恩..就是一个矩阵快速幂..矩阵就是原图的邻接矩阵..然后f[i][i]也是1.. 但是这是不会自爆的情况下的矩阵,算上自爆的话要把每次转移的结果求和..蒟蒻想了半天.. 然后发现其实只要再加一行一列,然后f[n+1][i]=1,就可以了.. 意会一下好了..矩阵什么的感觉讲不清楚啊.. 1 /* h

【矩阵乘法快速幂】

快速入门视频: av56433157 1> p1926 斐波那契 #include<cstdio> #include<cstdlib> #include<cstring> using namespace std; long long n; const int mod=1000000007; long long nw[2][2],ans[2][2]; long long t[2][2]; void mul1() { memset(t,0,sizeof(t)); fo