题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=6050
题目大意:
对Fx,y给出三个定义式,求Fm,1%1000000007之后的值
分析:
根据$F_{1,i} = F_{1,i-1} + 2*F_{1,i-2} $可以看出 F1,i−2F1,i−1成等比,然后迭代即可求得F1,i的通项,然后求和便是F2,1的值,之后发现,然后再对第二行的前n个数求和,得到F3,1即可发现答案,或者打表寻找在不同的n下,从F2,1到F3,1及后面多个数的变化即可发现
Fm,1={(2n−1)∗F2,1 n is even(2n−1)∗Fm−1,1−S1,n−1 n is odd
n为奇数时减去的常数也可以由打表找出,打表发现n=3时,F3,1=(23−1)∗F2,1−2 , n=5时,F3,1=(25−1)∗F2,1−10 ,而n=7时,常数为42,可以发现C(n−1)/2=4∗C(n−3]/2+2继续拆解构造数列通项式即可得到常数的表达式,然后快速幂即可得到答案,中间分数用逆元处理
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| #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; }
|