【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
");
 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
");
 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
",a);
123         else if(n == 2)
124             printf("%I64d
",b);
125         else
126         {
127             
128                 init();
129                 ma=matrixMul(ma,matrixPow(mb,n-2));
130         }
131         printf("%I64d
",ma.data[1][1]);
132     }
133     return 0;
134 }
原文地址:https://www.cnblogs.com/myx12345/p/9742139.html