Funny Function
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 350 Accepted Submission(s): 149
Problem Description
Function
Fx,y
satisfies:
For given integers N and M,calculate Fm,1 modulo 1e9+7.
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.
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
Source
解题思路:题意就不解释了,根据题目里给的式子去求,现场赛的时候两个队友一直用excel在那里找规律,最后找出了奇数和偶数时不同的递推式:
奇数:F(m,1)=F(m-1,1)*(2^n-1)-C(n/2),C(x)=C(x-1)*4+2
偶数:F(m,1)=(2^n-1)^(m-1)/3
然后矩阵快速幂搞一下就好了,奇数的时候最后答案要乘2
官方题解:
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <string>
- #include <algorithm>
- #include <map>
- #include <cmath>
- #include <set>
- #include <stack>
- #include <queue>
- #include <vector>
- #include <bitset>
- #include <functional>
- using namespace std;
- #define LL long long
- const int INF = 0x3f3f3f3f;
- const LL mod = 1000000007;
- LL n, m;
- struct Matrix
- {
- LL v[9][9];
- Matrix()
- {
- memset(v, 0, sizeof v);
- }
- } dan;
- Matrix mul(Matrix a, Matrix b, int d)
- {
- Matrix ans;
- for (int i = 0; i < d; i++)
- {
- for (int j = 0; j < d; j++)
- {
- for (int k = 0; k < d; k++)
- {
- ans.v[i][j] += (a.v[i][k] * b.v[k][j]) % mod;
- ans.v[i][j] %= mod;
- }
- }
- }
- return ans;
- }
- Matrix qpow(Matrix a, LL k, int d)
- {
- Matrix ans = dan;
- while (k)
- {
- if (k & 1) ans = mul(ans, a, d);
- k >>= 1;
- a = mul(a, a, d);
- }
- return ans;
- }
- LL qpow(LL x, LL y)
- {
- LL ans = 1;
- while (y)
- {
- if (y & 1) ans *= x, ans %= mod;
- y >>= 1;
- x *= x;
- x %= mod;
- }
- return ans;
- }
- LL extend_gcd(LL a, LL b, LL &x, LL &y)
- {
- if (!b)
- {
- x = 1, y = 0;
- return a;
- }
- LL gcd = extend_gcd(b, a%b, x, y);
- LL tmp = x;
- x = y;
- y = tmp - (a / b)*y;
- return gcd;
- }
- int main()
- {
- int t;
- scanf("%d", &t);
- while (t--)
- {
- scanf("%lld%lld", &n, &m);
- if (m == 1) { printf("1\n"); continue; }
- Matrix a, ans;
- LL ans1 = (qpow(2, n) - 1 + mod) % mod;
- if (n % 2)
- {
- dan.v[0][0] = 0, dan.v[0][1] = 1;
- a.v[0][0] = 4, a.v[0][1] = 0, a.v[1][0] = 2, a.v[1][1] = 1;
- ans = qpow(a, n / 2, 2);
- dan.v[0][0] = 1, dan.v[0][1] = 1;
- a.v[0][0] = ans1, a.v[0][1] = 0, a.v[1][0] = -ans.v[0][0], a.v[1][1] = 1;
- ans = qpow(a, m - 1, 2);
- printf("%lld\n", (ans.v[0][0]+mod)%mod);
- }
- else
- {
- ans1 = qpow(ans1, m - 1);
- LL x, y;
- extend_gcd(3, mod, x, y);
- ans1 = ans1*x%mod;
- ans1 = (ans1 * 2) % mod;
- printf("%lld\n", ans1);
- }
- }
- return 0;
- }
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
#include <cmath>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <functional>
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f;
const LL mod = 1000000007;
LL n, m;
struct Matrix
{
LL v[9][9];
Matrix()
{
memset(v, 0, sizeof v);
}
} dan;
Matrix mul(Matrix a, Matrix b, int d)
{
Matrix ans;
for (int i = 0; i < d; i++)
{
for (int j = 0; j < d; j++)
{
for (int k = 0; k < d; k++)
{
ans.v[i][j] += (a.v[i][k] * b.v[k][j]) % mod;
ans.v[i][j] %= mod;
}
}
}
return ans;
}
Matrix qpow(Matrix a, LL k, int d)
{
Matrix ans = dan;
while (k)
{
if (k & 1) ans = mul(ans, a, d);
k >>= 1;
a = mul(a, a, d);
}
return ans;
}
LL qpow(LL x, LL y)
{
LL ans = 1;
while (y)
{
if (y & 1) ans *= x, ans %= mod;
y >>= 1;
x *= x;
x %= mod;
}
return ans;
}
LL extend_gcd(LL a, LL b, LL &x, LL &y)
{
if (!b)
{
x = 1, y = 0;
return a;
}
LL gcd = extend_gcd(b, a%b, x, y);
LL tmp = x;
x = y;
y = tmp - (a / b)*y;
return gcd;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%lld%lld", &n, &m);
if (m == 1) { printf("1\n"); continue; }
Matrix a, ans;
LL ans1 = (qpow(2, n) - 1 + mod) % mod;
if (n % 2)
{
dan.v[0][0] = 0, dan.v[0][1] = 1;
a.v[0][0] = 4, a.v[0][1] = 0, a.v[1][0] = 2, a.v[1][1] = 1;
ans = qpow(a, n / 2, 2);
dan.v[0][0] = 1, dan.v[0][1] = 1;
a.v[0][0] = ans1, a.v[0][1] = 0, a.v[1][0] = -ans.v[0][0], a.v[1][1] = 1;
ans = qpow(a, m - 1, 2);
printf("%lld\n", (ans.v[0][0]+mod)%mod);
}
else
{
ans1 = qpow(ans1, m - 1);
LL x, y;
extend_gcd(3, mod, x, y);
ans1 = ans1*x%mod;
ans1 = (ans1 * 2) % mod;
printf("%lld\n", ans1);
}
}
return 0;
}