1. 程式人生 > >【HDOJ5950】Recursive sequence(矩陣乘法,快速冪)

【HDOJ5950】Recursive sequence(矩陣乘法,快速冪)

重點 模板 || getchar() 矩陣 col space pair color

題意: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 }

【HDOJ5950】Recursive sequence(矩陣乘法,快速冪)