题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=6050
题目大意:
对
Fx,y
给出三个定义式,求
Fm,1%1000000007
之后的值
分析:
根据
F1,i=F1,i−1+2∗F1,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 继续拆解构造数列通项式即可得到常数的表达式,然后快速幂即可得到答案,中间分数用逆元处理
代码:
#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;
}