题目链接:https://www.nowcoder.com/acm/contest/105/G
思路:这题一看数据范围就知道是个矩阵快速幂,通过构造矩阵知我们需要的转移矩阵为下图形式,不过需要特判1然后输出的是n-1的结果哦,因为这个我本题WA了==!矩阵快速幂最难得就是构造矩阵,当矩阵构造出来之后基本上就好做了~
1 #include <cstdio> 2 #include <cstring> 3 4 typedef long long ll; 5 const int mod = 1e9 + 7; 6 7 int t; 8 ll n; 9 10 void mul(int f[6], int a[6][6]) { 11 int c[6]; 12 memset(c, 0, sizeof(c)); 13 for(int i = 0; i < 6; i++) { 14 for(int j = 0; j < 6; j++) { 15 c[i] = (c[i] + (ll)f[j] * a[j][i] % mod) % mod; 16 } 17 } 18 memcpy(f, c, sizeof(c)); 19 } 20 21 void mulself(int a[6][6]) { 22 int c[6][6]; 23 memset(c, 0, sizeof(c)); 24 for(int i = 0; i < 6; i++) { 25 for(int j = 0; j < 6; j++) { 26 for(int k = 0; k < 6; k++) { 27 c[i][j] = (c[i][j] + (ll) a[i][k] * a[k][j] % mod) % mod; 28 } 29 } 30 } 31 memcpy(a, c, sizeof(c)); 32 } 33 34 int main() { 35 scanf("%d", &t); 36 while(t--) { 37 int f[6] = {1, 0, 1, 1, 1, 1}; 38 int a[6][6] = {{1, 1, 0, 0, 0, 0}, {1, 0, 0, 0, 0, 0}, {1, 0, 1, 0, 0, 0}, {4, 0, 3, 1, 0, 0}, {6, 0, 3, 2, 1, 0}, {4, 0, 1, 1, 1, 1}}; 39 scanf("%lld", &n); 40 n = n - 1; 41 for(; n; n >>= 1) { 42 if(n & 1) 43 mul(f, a); 44 mulself(a); 45 } 46 printf("%d ", f[0]); 47 } 48 return 0; 49 }
代码实现如下: