Funny Function
Time Limit: 2000/1000 MS (Java/Others) Memory Limit:32768/32768 K (Java/Others)
Total Submission(s): 284 Accepted Submission(s): 121
Problem Description
Function Fx,y satisfies:
For given integers N and M,calculate
Fm,1 modulo 1e9+7.
Input
There is one integer T in the first line.
The next T lines,each line includes two integers N and M .
1<=T<=10000,1<=N,M<2^63.
Output
For each given N and M,print the answer in a single line.
Sample Input
2
2 2
3 3
Sample Output
2
33
【题意】给出递推公式,递推公式与n有关,求F[m][1]的值。
【思路】这道题我们可以经过打表发现最终的递推公式与n有关:
当n为偶数时:F(m,1)=(2^n -1)^(m-1)*2/3
当n为奇数时:F(m,1)=((2^n -1)^(m-1)*2+1)/3
这样的话可以直接利用快速幂求解,值得注意的是,这里涉及到除法取膜,由于除法取膜不满足公式,所以要求3对于1e9+7的逆元,由拓展欧几里得算法或者费马小定理可以得到逆元为333333336,代入即可。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define rush() int T;scanf("%d",&T);while(T--)
typedef unsigned long long ll;
const int maxn = 100005;
const ll mod = 1e9+7;
const ll inv = 333333336;
const int INF = 0x3f3f3f;
const double eps = 1e-9;
ll fast_mod(ll a,ll b,ll Mod)
{
ll ans=1;
a%=Mod;
while(b)
{
if(b&1)
ans=(ans*a)%Mod;
b>>=1;
a=(a*a)%Mod;
}
return ans;
}
int main()
{
ll n,m;
rush()
{
scanf("%I64d%I64d",&n,&m);
if(m==1)
{
puts("1");
continue;
}
ll temp=(fast_mod(2,n,mod)-1+mod)%mod;
ll ans;
if(n&1)
{
ans=(2*fast_mod(temp,m-1,mod)+1)*inv%mod;
}
else
{
ans=2*fast_mod(temp,m-1,mod)*inv%mod;
}
printf("%I64d\n",ans);
}
return 0;
}