Function Fx,ysatisfies:
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,M让你求满足上述三个式子的函数F(i,j).
求F(m,1)的值;
解题思路:一道数学题,数那么大肯定不能硬算,把式子化简得到能使用矩阵快速幂的公式。
化简过程如下:
AC代码:
#include <iostream>
#include <cstring>
#include<stdio.h>
using namespace std;
#define SIZE 2
struct matrix
{
long long e[SIZE][SIZE];
matrix()
{
memset(e, 0, sizeof(e));
}
} A, A_n;
const long long mod = 1e9+7; //上限
matrix operator*(matrix &a, matrix &b)///两个矩阵相乘,行上的每个元素对应乘以列上的每个元素然后求和
{
matrix t;
for (int i = 0; i < SIZE; ++i)
{
for (int j = 0; j < SIZE; ++j)
{
for (int k = 0; k < SIZE; ++k)
{
t.e[i][j] += a.e[i][k]*b.e[k][j];
t.e[i][j] %= mod;
}
}
}
return t;
}
matrix quickpower(matrix &a, long long b)///求矩阵的a的b次方,原理同整数幂一样
{
matrix ans;
for (int i = 0; i < SIZE; ++i)
{
ans.e[i][i] = 1;
}
while (b)
{
if (b & 1) ans = ans * a;
b >>= 1;
a = a * a;
}
return ans;
}
int main(int argc, char const *argv[])
{
int testn;
scanf("%d", &testn);
while (testn--)
{
long long n, m;
scanf("%I64d %I64d", &n, &m);
///矩阵A
A.e[0][0] = 0;
A.e[1][0] = A.e[1][1] = 1;
A.e[0][1] = 2;
///求得矩阵An
A_n = quickpower(A, n);
matrix b;
if(n & 1)
{
///矩阵B1
b.e[0][0] = -1;
b.e[0][1] = 2;
b.e[1][0] = 1;
b.e[1][1] = 0;
}
else
{
///矩阵B0
b.e[0][0] = b.e[1][1] = 1;
b.e[0][1] = b.e[1][0] = 0;
}
///矩阵An-B0(B1)
A_n.e[0][0] -= b.e[0][0];
A_n.e[0][1] -= b.e[0][1];
A_n.e[1][0] -= b.e[1][0];
A_n.e[1][1] -= b.e[1][1];
A_n = quickpower(A_n, m-1);
long long ans = (A_n.e[0][0] + A_n.e[1][0]) % mod;
printf("%I64d\n", ans);
}
return 0;
}
还有直接推通项的直接得到:
F(m,1)=(2*k1^(m-1)+(1+(-1)^(n+1))/2)/3 其中k1=(2^n-1);
然后直接求。 (不是一般人能做的)
还有就是观察规律得到这个公式没啥说的。
AC代码:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 1e5 + 10;
const int mod = 1e9 + 7;
typedef long long LL;
LL km(LL a,LL b){
LL ans = 1;
while(b){
if(b & 1) ans = (ans * a) % mod;
b >>= 1; a = (a * a) % mod;
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
LL n,m;
scanf("%lld %lld",&n,&m);
LL k = (km(2,n) - 1 + mod) % mod;
LL k1 = (km(k,m - 1) * 2) % mod;
LL k2 = (1 + km(-1,n + 1)) * km(2,mod - 2);
printf("%lld\n",((k1 + k2) % mod * km(3,mod - 2)) % mod);
}
return 0;
}