这个题有两种解法,一个是等比数列加快速幂,二是矩阵快速幂。
矩阵快速幂很好做,代码这里不写了:题目已知奇数项a[n]=a[n-1]*2+1,偶数项a[n]=a[n-1]*2。分别拆分可得奇数:a[n]=a[n-1]+2*a[n-2]+1,偶数项:a[n]=a[n-1]+2*a[n-2]+1。发现都是同一个式子,所以直接矩阵快速幂就可以了
等比数列就是列出前几项观察可得a[n]=2^(n-1)+2^(n-3)+2^(n-5)+....然后分奇偶得出奇数时为(2^(n+1)-1)/3,偶数时得出为(2^(n)-1)*2/3。
这个题场上做的时候没发现模m其实是变化的,所以可能存在逆元不存在的情况,所以拓展欧几里得和费马求逆元都不行,这里用的是除法取模
(a/b)%m就等于a%(b*m)/b,证明如下
(a/b)%m=c ==> a/b+c=k*m
==> a+b*c=k*m*b
==> a%(m*b)=b*c
==> a%(m*b)/b=c
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
using namespace std;
typedef long long int ll;
ll n,m;
ll qp(ll a,ll b,ll mod)
{
ll res=1;
while(b)
{
if(b%2) res=(res*a)%mod;
a=(a*a)%mod;
b/=2;
}
return res;
}
int main()
{
while(scanf("%lld%lld",&n,&m)!=EOF)
{
ll ans;
if(n%2)
{
ans=(qp(2,n+1,3*m)-1)%(3*m)/3;//注意整个过程都要对3*m取模
}
else
{
ans=(qp(2,n,3*m)-1)%(3*m)/3;
ans=ans*2%m;
}
printf("%lld\n",ans);
}
return 0;
}