0%

Hdu 6050 - Funny Function(打表推导)

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

题目大意:
Fx,yF_{x,y}给出三个定义式,求Fm,1%1000000007F_{m,1}\%1000000007之后的值

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

Fm,1={2n1)F2,1   n is even(2n1)Fm1,1S1,n1   n is oddF_{m,1} =\begin{cases} &(2^n-1)*F_{2,1} \space\space\space n \space is\space even\\ & (2^n-1)*F_{m-1,1}-S_{1,n-1} \space\space\space n\space is \space odd\end{cases}

n为奇数时减去的常数也可以由打表找出,打表发现n=3n=3时,F3,1=(231)F2,12F_{3,1} = (2^3 -1)*F_{2,1} - 2 , n=5n=5时,F3,1=(251)F2,110F_{3,1} = (2^5-1)*F_{2,1} - 10 ,而n=7n=7时,常数为42,可以发现C(n1)/2=4C(n3]/2+2C_{(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;
}