题目链接:点击这里
题目大意:
给定正整数
n
,
c
,
k
n,c,k
n,c,k 求:
∑
i
=
0
n
F
(
i
c
)
k
m
o
d
1
e
9
+
9
\sum_{i=0}^nF(ic)^k \mod 1e9+9
i=0∑nF(ic)kmod1e9+9
其中
F
(
i
)
F(i)
F(i) 为斐波那契数列的第
i
i
i 项
题目分析:
我们知道斐波那契数列的通项如下:
F
(
n
)
=
1
5
(
(
1
+
5
2
)
n
−
(
1
−
5
2
)
n
)
F(n) = \frac 1 {\sqrt 5}((\frac{1+\sqrt5} 2)^n-(\frac {1-\sqrt 5} 2)^n)
F(n)=51((21+5)n−(21−5)n)
我们先看一下
c
=
1
c=1
c=1 这特殊情况,此时就是求斐波那契数列的幂次和:
F
(
n
)
k
=
1
(
5
)
k
(
(
1
+
5
2
)
n
−
(
1
−
5
2
)
n
)
k
F(n)^k= \frac 1 {(\sqrt 5)^k}((\frac{1+\sqrt5} 2)^n-(\frac {1-\sqrt 5} 2)^n)^k
F(n)k=(5)k1((21+5)n−(21−5)n)k
设
a
=
1
+
5
2
,
b
=
1
−
5
2
a=\frac{1+\sqrt5} 2,b=\frac {1-\sqrt 5} 2
a=21+5,b=21−5 :
F
(
n
)
k
=
1
(
5
)
k
(
a
n
−
b
n
)
k
F(n)^k=\frac 1 {(\sqrt 5)^k}(a^n-b^n)^k
F(n)k=(5)k1(an−bn)k
把
(
a
n
−
b
n
)
k
(a^n-b^n)^k
(an−bn)k 用二项式定理展开:
(
a
n
−
b
n
)
k
=
C
k
0
(
a
n
)
k
(
−
b
n
)
0
+
C
k
1
(
a
n
)
k
−
1
(
−
b
n
)
1
+
.
.
.
+
C
k
r
(
a
n
)
k
−
r
(
−
b
n
)
r
+
.
.
.
+
C
k
k
(
a
n
)
0
(
−
b
n
)
k
(a^n-b^n)^k=C_k^0(a^n)^k(-b^n)^0+C_k^1(a^n)^{k-1}(-b^n)^1+...+C_k^r(a^n)^{k-r}(-b^n)^r+...+C_k^k(a^n)^0(-b^n)^k
(an−bn)k=Ck0(an)k(−bn)0+Ck1(an)k−1(−bn)1+...+Ckr(an)k−r(−bn)r+...+Ckk(an)0(−bn)k
=
(
−
1
)
0
C
k
0
(
a
n
)
k
(
b
n
)
0
+
(
−
1
)
1
C
k
1
(
a
n
)
k
−
1
(
b
n
)
1
+
.
.
.
+
(
−
1
)
r
C
k
r
(
a
n
)
k
−
r
(
b
n
)
r
+
.
.
.
+
(
−
1
)
k
C
k
k
(
a
n
)
0
(
b
n
)
k
=(-1)^0C_k^0(a^n)^k(b^n)^0+(-1)^1C_k^1(a^n)^{k-1}(b^n)^1+...+(-1)^rC_k^r(a^n)^{k-r}(b^n)^r+...+(-1)^kC_k^k(a^n)^0(b^n)^k
=(−1)0Ck0(an)k(bn)0+(−1)1Ck1(an)k−1(bn)1+...+(−1)rCkr(an)k−r(bn)r+...+(−1)kCkk(an)0(bn)k
=
(
−
1
)
0
C
k
0
(
a
k
)
n
(
b
0
)
n
+
(
−
1
)
1
C
k
1
(
a
k
−
1
)
n
(
b
1
)
n
+
.
.
.
+
(
−
1
)
r
C
k
r
(
a
k
−
r
)
n
(
b
r
)
n
+
.
.
.
+
(
−
1
)
k
C
k
k
(
a
0
)
n
(
b
k
)
n
=(-1)^0C_k^0(a^k)^n(b^0)^n+(-1)^1C_k^1(a^{k-1})^{n}(b^1)^n+...+(-1)^rC_k^r(a^{k-r})^{n}(b^r)^n+...+(-1)^kC_k^k(a^0)^n(b^k)^n
=(−1)0Ck0(ak)n(b0)n+(−1)1Ck1(ak−1)n(b1)n+...+(−1)rCkr(ak−r)n(br)n+...+(−1)kCkk(a0)n(bk)n
对于每一项都这么表示会发现提出
C
k
r
C_k^r
Ckr 后括号里的是一个公比为
a
k
−
r
b
r
a^{k-r}b^r
ak−rbr 的等比数列,合并后的和为
(
−
1
)
r
C
k
r
t
(
1
−
t
n
)
1
−
t
(-1)^rC_k^r\frac {t(1-t^n)}{1-t}
(−1)rCkr1−tt(1−tn) 其中
t
=
a
k
−
r
b
r
t=a^{k-r}b^r
t=ak−rbr
所以有:
∑
i
=
0
n
F
(
i
)
=
1
(
5
)
k
∑
i
=
0
k
(
−
1
)
i
C
k
i
t
(
1
−
t
n
)
1
−
t
(
t
=
a
k
−
i
b
i
)
\sum_{i=0}^nF(i)=\frac 1 {(\sqrt 5)^k}\sum_{i=0}^k(-1)^iC_k^i\frac {t(1-t^n)}{1-t}(t=a^{k-i}b^i)
i=0∑nF(i)=(5)k1i=0∑k(−1)iCki1−tt(1−tn)(t=ak−ibi)
有了这个式子以后我们就可以更轻松的解决所求问题了,此时我们加上
c
c
c 的限制:
F
(
c
n
)
k
=
1
(
5
)
k
(
(
1
+
5
2
)
c
n
−
(
1
−
5
2
)
c
n
)
k
F(cn)^k=\frac 1 {(\sqrt 5)^k}((\frac{1+\sqrt5} 2)^{cn}-(\frac {1-\sqrt 5} 2)^{cn})^k
F(cn)k=(5)k1((21+5)cn−(21−5)cn)k
于是有:
∑
i
=
0
n
F
(
c
n
)
k
=
1
(
5
)
k
∑
i
=
0
k
(
−
1
)
i
C
k
i
t
(
1
−
t
n
)
1
−
t
(
t
=
(
a
k
−
i
b
i
)
c
)
\sum_{i=0}^nF(cn)^k=\frac 1 {(\sqrt 5)^k}\sum_{i=0}^k(-1)^iC_k^i\frac {t(1-t^n)}{1-t}(t=(a^{k-i}b^i)^c)
i=0∑nF(cn)k=(5)k1i=0∑k(−1)iCki1−tt(1−tn)(t=(ak−ibi)c)
接下来便是计算问题了:
我们首先求出
5
5
5 的二次剩余即
x
2
≡
5
m
o
d
1
e
9
+
9
x^2\equiv5\mod 1e9+9
x2≡5mod1e9+9 的解是
383008016
383008016
383008016
然后再用逆元计算出
a
,
b
a,b
a,b 的值,
a
=
691504013
,
b
=
308495997
a=691504013,b=308495997
a=691504013,b=308495997
这个题还需要卡一下常数,卡常用的方法:
- 欧拉降幂: a x m o d p = a x % ( p − 1 ) m o d p a^x \mod p=a^{x\%(p-1)} \mod p axmodp=ax%(p−1)modp
- 不提前处理 a k − i b i ) c a^{k-i}b^i)^c ak−ibi)c 边循环边乘 a b \frac a b ba
具体细节见代码:
#pragma GCC optimize(2)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
ll read()
{
ll res = 0,flag = 1;
char ch = getchar();
while(ch<'0' || ch>'9')
{
if(ch == '-') flag = -1;
ch = getchar();
}
while(ch>='0' && ch<='9')
{
res = (res<<3)+(res<<1)+(ch^48);//res*10+ch-'0';
ch = getchar();
}
return res*flag;
}
const int maxn = 1e5+5;
const int mod = 1e9+9;
const double pi = acos(-1);
const double eps = 1e-8;
const int a = 691504013;
const int b = 308495997;
const int inv5 = 383008016;
ll n,k,c,fac[maxn],A[maxn],B[maxn],inv[maxn];
ll qpow(ll a,ll b)
{
ll res = 1;
while(b)
{
if(b&1) res = res*a%mod;
a = a*a%mod;
b >>= 1;
}
return res;
}
void init() //计算阶乘和ab的幂次
{
fac[0] = inv[0] = A[0] = B[0] = 1;
for(int i = 1;i < maxn;i++)
{
fac[i] = fac[i-1]*i%mod;
// A[i] = A[i-1]*a%mod;
// B[i] = B[i-1]*b%mod;
inv[i] = qpow(fac[i],mod-2);
}
// inv[maxn-1] = qpow(fac[maxn-1],mod-2);
// for(int i = maxn-1;i;i--)
// inv[i-1] = inv[i]*i%mod;
}
int main()
{
ll t = read();
init();
while(t--)
{
n = read(),c = read(),k = read();
ll ans = 0;
ll A = qpow(::a,c%(mod-1)),B = qpow(::b,c%(mod-1));
ll a = 1,b = qpow(B,k),invb = qpow(B,mod-2);
for(int i = 0;i <= k;i++)
{
// ll x = qpow(A[k-i]*B[i]%mod,c); //公比
ll x = a*b%mod;
ll C = fac[k]*inv[k-i]%mod*inv[i]%mod;
ll sum = x*(qpow(x,n%(mod-1))-1)%mod*qpow(x-1,mod-2)%mod;
if(x == 1) sum = n%mod;
sum = sum*C%mod;
if((k-i)&1) ans = (ans-sum)%mod;
else ans = (ans+sum)%mod;
a = a*A%mod;
b = b*invb%mod;
}
ll num = qpow(inv5,mod-2);
ans = ans*qpow(num,k)%mod;
printf("%lld\n",(ans%mod+mod)%mod);
}
return 0;
}