刚开始TLE以为是 矩阵相乘超时,改了发现还有错,然后....今天在看的时候发现有一种n == 0的情况,改了以后不TLE,改成WA了,然后....就将int变为longlong。AC
/*矩阵快速幂*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
//const int mod = 10000;
typedef long long LL;
const int maxn = 20;
const int M[maxn+5] = {1, 10, 100, 1000, 10000};
LL mod;
//int N;
struct Matrix {
LL mat[maxn][maxn];
int x, y;
Matrix() {
memset(mat, 0, sizeof(mat));
for (int i = 1; i <= maxn - 5; i++)
mat[i][i] = 1;
}
};
inline void mat_mul(Matrix a, Matrix b, Matrix &c) {
memset(c.mat, 0, sizeof(c.mat));
c.x = a.x; c.y = b.y;
for (int i = 1; i <= c.x; i++) {
for (int j = 1; j <= c.y; j++) {
for (int k = 1; k <= a.y; k++) {
c.mat[i][j] += (a.mat[i][k] * b.mat[k][j]) % mod;
c.mat[i][j] %= mod;
}
}
}
return ;
}
//快速幂
inline void mat_pow(Matrix &a, int z) {
Matrix ans, base = a;
ans.x = a.x; ans.y = a.y;
while (z) {
if (z & 1 == 1) mat_mul(ans, base, ans);
mat_mul(base, base, base);
z >>= 1;
}
a = ans;
}
int main() {
/* int t;
cin >> t;*/
LL a, b, n, m;
while(cin >> n >> m)
{
if(n == 0){
cout << 0 << endl;
continue;
}
a = 0, b = 1;
mod = pow(2, m);
Matrix A, B;
A.x = 2; A.y = 2;
A.mat[1][1] = 1; A.mat[1][2] = 1;
A.mat[2][1] = 1; A.mat[2][2] = 0;
B.x = 2; B.y = 1;
B.mat[1][1] = b; B.mat[2][1] = a;
mat_pow(A, n - 1);
mat_mul(A, B, B);
cout << B.mat[1][1] << endl;
}
return 0;
}
/*矩阵快速幂*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
//const int mod = 10000;
typedef long long LL;
const int maxn = 20;
const int M[maxn+5] = {1, 10, 100, 1000, 10000};
LL mod;
//int N;
struct Matrix {
LL mat[maxn][maxn];
int x, y;
Matrix() {
memset(mat, 0, sizeof(mat));
for (int i = 1; i <= maxn - 5; i++)
mat[i][i] = 1;
}
};
inline void mat_mul(Matrix a, Matrix b, Matrix &c) {
memset(c.mat, 0, sizeof(c.mat));
c.x = a.x; c.y = b.y;
/* for (int i = 1; i <= c.x; i++) {
for (int j = 1; j <= c.y; j++) {
for (int k = 1; k <= a.y; k++) {
c.mat[i][j] += (a.mat[i][k] * b.mat[k][j]) % mod;
c.mat[i][j] %= mod;
}
}
}
*/
//仅适用于2*2
for (int i = 1; i <= 2; i++)
for (int j = 1; j <= 2; j++)
c.mat[i][j] = (a.mat[i][1] * b.mat[1][j] + a.mat[i][2] * b.mat[2][j]) % mod;
return ;
}
//快速幂
inline void mat_pow(Matrix &a, int z) {
Matrix ans, base = a;
ans.x = a.x; ans.y = a.y;
while (z) {
if (z & 1 == 1) mat_mul(ans, base, ans);
mat_mul(base, base, base);
z >>= 1;
}
a = ans;
}
int main() {
/* int t;
cin >> t;*/
LL a, b, n, m;
while(~scanf("%lld%lld", &n, &m))
{
if(n == 0){
printf("%lld\n", n);
continue;
}
a = 0, b = 1;
mod = pow(2, m);
Matrix A, B;
A.x = 2; A.y = 2;
A.mat[1][1] = 1; A.mat[1][2] = 1;
A.mat[2][1] = 1; A.mat[2][2] = 0;
B.x = 2; B.y = 1;
B.mat[1][1] = b; B.mat[2][1] = a;
mat_pow(A, n - 1);
mat_mul(A, B, B);
printf("%lld\n", B.mat[1][1]);
}
return 0;
}