HDU6050-Funny Function

来源:互联网 发布:医疗器械软件分类 编辑:程序博客网 时间:2024/06/11 12:26

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,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
22 23 3
 

Sample Output
233
 

Source
2017 Multi-University Training Contest - Team 2
 


解题思路:题意就不解释了,根据题目里给的式子去求,现场赛的时候两个队友一直用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


官方题解:

对于任意i>=1,当j>=3时,有 1 通过归纳法可以得到

  2 进而推导出3 通过矩阵快速幂求解


#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;}