/*
打表找到公式,矩阵快速幂加速- -
马虎:ll 类型 写成int , 一直 wrong T.T
1-7^n / 1-7
f(n) =2^(n-1)+f(n-2)
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int mod =1e9+7;
struct mex
{
int a[4][4];
}m1[6];
mex Plus(mex a,mex b)
{
mex c;ll d;
memset(c.a,0,sizeof(c.a));
for(int i=1;i<=3;++ i)
for(int j=1;j<=3;++ j)
for(int k=1;k<=3; ++ k)
{
d=a.a[i][k];
d *=b.a[k][j];
d %=mod;
c.a[i][j] =(c.a[i][j]+d)%mod;
}
return c;
}
ll quickm(ll n,ll m)
{
ll a=1,x=n;
while(m)
{
if(m&1) a =(a*x)%mod;
x=(x*x)%mod;
m /=2;
}
return a%mod;
}
void gcd(ll a,ll b,ll &d,ll &x,ll &y)
{
if(!b) {d=1;x=1;y=0;}
else
{
gcd(b,a%b,d,y,x); y-= x*(a/b);
}
}
int inc(int a,int mod)
{
ll x,y,d;
gcd(a,mod,d,x,y);
return d==1?(x+mod)%mod:-1;
}
void init()
{
m1[1].a[1][1]=1;
m1[1].a[2][1]=4;
m1[1].a[3][1]=2;
memset(m1[2].a,0,sizeof(m1[2].a));
m1[2].a[1][3]=1;m1[2].a[3][1]=1;m1[2].a[3][2]=1;
m1[2].a[2][2]=2;
}
int main()
{
int t;
ll n,m;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld",&n,&m);
ll n0,nn=n;
if(m==1||n==1) { printf("1\n"); continue;}
init();
n0=n-1;n -=2;
while(n)
{
if(n&1) m1[1]=Plus(m1[2],m1[1]);
m1[2]=Plus(m1[2],m1[2]);
n /=2;
}
int a1=m1[1].a[3][1],a0=0;
if(n0==1) a0=1;
if(!a0)
{
n=n0;n -=2;
init();
while(n)
{
if(n&1) m1[1]=Plus(m1[2],m1[1]);
m1[2]=Plus(m1[2],m1[2]);
n /=2;
}
a0=m1[1].a[3][1];
}
if(m==2)
{
printf("%d\n",a1);
continue;
}
int dos=(a0+a1)%mod;
ll d=quickm(dos,m-2);
ll ans=(ll)d*a1%mod;
if(nn%2)
{
int ink=inc(dos-1,mod);
ll dd =ink;dd *=d-1; dd%=mod; dd *=a0;dd %=mod;
ans -=dd;
ans =(ans+mod)%mod;
}
printf("%lld\n",ans);
}
return 0;
}
hdu 6050 Funny Function
最新推荐文章于 2017-08-05 16:28:12 发布