题意要求输出题目中代码的输出
代码很好理解 i从1到n i为奇数时ans=ans*2+1 i为偶数时ans*=2
可以把两步操作合成到一起 即 ans=ans*4+2 然后执行n/2次 (n为奇数就再补上一次即可)
然后用矩阵快速幂就可以了
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include<set>
#include<stack>
#define bug puts("bugbugbug");
using namespace std;
typedef long long ll;
const int maxn = 20;
const int maxm = 20;
ll mod, k;
struct Matrix
{
int n, m;
long long a[maxn][maxm];
void clear()
{
n = m = 0;
memset(a, 0, sizeof(a));
}
Matrix operator * (const Matrix &b) const //实现矩阵乘法
{
Matrix tmp;
tmp.n = n;
tmp.m = b.m;
for (int i = 0; i < n; i++)
for (int j = 0; j < b.m; j++) tmp.a[i][j] = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
if (!a[i][j]) continue;
for (int k = 0; k < b.m; k++)
tmp.a[i][k] += a[i][j] * b.a[j][k], tmp.a[i][k] %= mod;
}
return tmp;
}
void Copy(const Matrix &b)
{
n = b.n, m = b.m;
for (int i = 0; i < n; i++)
for(int j = 0; j < m; j++) a[i][j] = b.a[i][j];
}
void unit(int sz)
{
n = m = sz;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++) a[i][j] = 0;
a[i][i] = 1;
}
}
};
Matrix A, B,C,D;
void init()
{
A.clear();
A.n=A.m=2;
A.a[0][0]=4;
A.a[0][1]=2;
A.a[1][0]=0;
A.a[1][1]=1;
D.clear();
D.n=D.m=2;
D.a[0][0]=2;
D.a[0][1]=1;
D.a[1][0]=0;
D.a[1][1]=1;
B.clear();
B.n = 2;
B.m = 1; //矩阵B是f(x)的前10个数
B.a[0][0] = 0;
B.a[1][0]=1;
}
Matrix Matrix_pow(Matrix A, ll k, ll mod) //矩阵快速幂
{
Matrix res;
res.clear();
res.n = res.m = A.n;
for (int i = 0; i < A.n; i++) res.a[i][i] = 1;
while(k)
{
if (k & 1) res.Copy(A * res);
k >>= 1;
A.Copy(A * A);
}
return res;
}
int main()
{
long long n,m;
init();
while(~scanf("%lld%lld",&n,&m))
{
mod=m;
int flag=0;
if(n%2)
{
n-=1;
flag++;
}
C.Copy(Matrix_pow(A,n/2,m));
C.Copy(C*B);
if(flag)
C.a[0][0]=(C.a[0][0]*2+1)%m;
printf("%d\n",C.a[0][0]);
}
return 0;
}