Hdu 6050

来源:互联网 发布:java apache 编辑:程序博客网 时间:2024/05/01 06:32

题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=6050

题目大意:
Fx,y给出三个定义式,求Fm,1%1000000007之后的值

分析:
根据F1,i=F1,i1+2F1,i2可以看出 F1,i2F1,i1成等比,然后迭代即可求得F1,i的通项,然后求和便是F2,1的值,之后发现,然后再对第二行的前n个数求和,得到F3,1即可发现答案,或者打表寻找在不同的n下,从F2,1F3,1及后面多个数的变化即可发现

Fm,1={2n1)F2,1   n is even(2n1)Fm1,1S1,n1   n is odd

n为奇数时减去的常数也可以由打表找出,打表发现n=3时,F3,1=(231)F2,12 , n=5时,F3,1=(251)F2,110 ,而n=7时,常数为42,可以发现C(n1)/2=4C(n3]/2+2继续拆解构造数列通项式即可得到常数的表达式,然后快速幂即可得到答案,中间分数用逆元处理

代码:

#include <bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 2e5+200;const int mod = 1e9+7;ll n,m;ll f[200],arr[20][1000];ll quickpow(ll a,ll n){    ll res = 1;    while (n)    {        if (n&1)    res = res*a%mod;        a = a*a %mod;        n >>= 1;    }    return res;}int main() {    int T,t=1;    ll rst = quickpow(3,mod-2);    ll rss = quickpow(2,mod-2);    scanf("%d",&T);    while (T--)    {        scanf("%lld%lld",&n,&m);        ll tnp = quickpow(2,n);        ll fsone = ((tnp*2-2+(n&1))*rst)%mod , p =tnp - 1;        ll rs = quickpow(p-1,mod-2);        if (m==1)            printf("1\n");        else   if (n&1)        {            ll d = (tnp-2)%mod*rst%mod;            ll ans = (fsone-d*rs%mod+mod)%mod*quickpow(p,m-2)%mod+d*rs%mod;            printf("%lld\n",ans%mod);        }        else        {            ll ans = fsone*quickpow(tnp-1,m-2)%mod;            printf("%lld\n",ans);        }    }    return 0;}