传送门
题意
利用给出的式子求(F_{m,1})
分析
直接推公式(都是找规律大佬)
(n为偶数,F_{m,1}=frac{2(2^n-1)^{m-1}}3)
(n为奇数,F_{m,1}=F_{m-1,1}(2^n-1)-frac{2(4^{frac n2}-1)}3)
抱歉啊,markdown矩阵相乘实在调不出来了,勉强看一看吧QAQ
(
left[
egin{matrix}
2^n-1&-1 \
0&1
end{matrix}
ight] ag{3}
)
(
left[
egin{matrix}
F_{m-1,1} \
frac{2(4^{frac n2}-1)}3
end{matrix}
ight] ag{3}
) (=) (
left[
egin{matrix}
F_{m,1}\
frac{2(4^{frac n2}-1)}3
end{matrix}
ight] ag{3}
)
做一次矩阵快速幂即可
trick
m为1,n为偶数直接输出1
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define F(i,a,b) for(int i=a;i<=b;++i)
#define R(i,a,b) for(int i=a;i<b;++i)
#define mem(a,b) memset(a,b,sizeof(a))
const int N = 2;
const ll mod = 1e9+7;
int t;
ll n,m,n_2,n_4,ni_3;
struct matrix
{
ll mp[N][N];
matrix()
{
mem(mp,0);
}
};
ll pow_mod(ll a,ll p)
{
ll ans=1;
for(ll ret=a%mod;p;p>>=1,ret=ret*ret%mod) if(p&1) ans=ans*ret%mod;
return ans;
}
matrix mul(matrix a,matrix b)//矩阵相乘
{
matrix ans;
R(i,0,2)R(j,0,2)R(k,0,2) (ans.mp[i][j]+=a.mp[i][k]*b.mp[k][j]%mod)%=mod;
return ans;
}
matrix matrix_pow_mod(matrix a,ll p)
{
matrix ans,ret;
R(i,0,2)R(j,0,2) ret.mp[i][j]=a.mp[i][j];
ans.mp[0][0]=ans.mp[1][1]=1;
while(p)
{
if(p&1) ans=mul(ans,ret);
ret=mul(ret,ret);
//R(i,0,2)R(j,0,2) printf("%I64d%c", ret.mp[i][j],j==1?'
':' ');
p>>=1;
}
return ans;
}
void init()
{
n_2=(pow_mod(2LL,(ll)n)-1+mod)%mod;//求2^n-1
n_4=(pow_mod(4LL,(ll)(n/2))-1+mod)%mod;//求4^n-1
ni_3=pow_mod(3LL,mod-2);//求3的逆元
n_4=n_4*2%mod*ni_3%mod;
}
void work1()
{
matrix temp,ret;
temp.mp[0][0]=n_2,temp.mp[0][1]=-1;
temp.mp[1][0]=0,temp.mp[1][1]=1;
ret=matrix_pow_mod(temp,(ll)(m-1));//矩阵快速幂
ll ans=0;
//R(i,0,2)R(j,0,2) printf("%I64d
",ret.mp[i][j] );
ans=(ret.mp[0][0]+ret.mp[0][1]*n_4%mod+mod)%mod;
while(ans<0) ans+=mod;
printf("%I64d
",ans );
}
void work2()
{
ll ans=pow_mod(n_2,(ll)(m-1));
ans=ans*2%mod*ni_3%mod;
ans=(ans+mod)%mod;
printf("%I64d
",ans );
}
int main()
{
for(scanf("%d",&t);t--;)
//F(i,1,10)F(j,1,10)
{
scanf("%lld %lld",&n,&m);
//n=i,m=j;printf("n=%I64d m=%I64d
",n,m );
init();
if(m==1) { puts("1");continue; }
if(n&1) work1();else work2();
}
return 0;
}