题面:
题意:
求
∑
i
=
0
n
(
F
c
∗
i
)
k
m
o
d
1000000009
\sum_{i=0}^n(F_{c*i})^k\space mod \space1000000009
∑i=0n(Fc∗i)k mod 1000000009
c
,
n
<
=
1
e
18
,
k
<
=
1
e
5
c,n<=1e18,k<=1e5
c,n<=1e18,k<=1e5
题解:
首先认识到,1000000009 是一个质数,且 5 是模 1000000009 的二次剩余,即
x
2
=
5
(
m
o
d
1000000009
)
x^2=5(mod \space 1000000009)
x2=5(mod 1000000009) 有解,那么我们解出 x 来就可以代替
5
\sqrt5
5 进行计算。
①斐波那契通项:
F
n
=
1
5
[
(
1
+
5
2
)
n
−
(
1
−
5
2
)
n
]
F_n=\frac{1}{\sqrt5}[ (\frac{1+\sqrt5}{2})^n-(\frac{1-\sqrt5}{2})^n]
Fn=51[(21+5)n−(21−5)n]
②、
我
们
令
a
=
1
+
5
2
,
b
=
1
−
5
2
)
我们令 a=\frac{1+\sqrt5}{2},b=\frac{1-\sqrt5}{2})
我们令a=21+5,b=21−5)
有
F
n
=
1
5
(
a
n
−
b
n
)
−
−
>
F
n
k
=
(
1
5
)
k
(
a
n
−
b
n
)
k
有F_n=\frac{1}{\sqrt5}(a^n-b^n)-->F_n^k=(\frac{1}{\sqrt5})^k(a^n-b^n)^k
有Fn=51(an−bn)−−>Fnk=(51)k(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
化简后有:
(
a
n
−
b
n
)
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
(a^n-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
(an−bn)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
对于每一个 ( F c ∗ i ) k (F_{c*i})^k (Fc∗i)k都这样表示,那么 ( − 1 ) r C k r (-1)^rC_k^r (−1)rCkr项合并后为等比数列。(其中 i == 0 时, ( F c ∗ i ) k (F_{c*i})^k (Fc∗i)k为0,可以忽略)。
等比数列
a
1
=
a
c
∗
(
k
−
r
)
b
c
∗
(
r
)
,
q
=
a
c
∗
(
k
−
r
)
b
c
∗
(
r
)
,
n
=
n
a_1=a^{c*(k-r)}b^{c*(r)},q=a^{c*(k-r)}b^{c*(r)},n=n
a1=ac∗(k−r)bc∗(r),q=ac∗(k−r)bc∗(r),n=n
那么求和为,
s
u
m
=
(
−
1
)
r
C
k
r
∗
q
∗
(
q
n
−
1
)
q
−
1
sum=(-1)^rC_k^r*\frac{q*(q^n-1)}{q-1}
sum=(−1)rCkr∗q−1q∗(qn−1)
当
q
≠
1
q\neq1
q=1时,可以直接用公式计算
当
q
=
1
q=1
q=1时,就是长度为 n 的首项为 1 的常数列。
③、
x
2
=
5
(
m
o
d
1000000009
)
x^2=5(mod \space 1000000009)
x2=5(mod 1000000009)的一个解
x
=
383008016
x=383008016
x=383008016
在模1e9+9的意义下,
i
n
v
(
2
)
=
500000005
inv(2)=500000005
inv(2)=500000005
那么
a
=
(
1
+
5
)
∗
i
n
v
(
2
)
=
691504013
,
b
=
(
1
−
5
)
∗
i
n
v
(
2
)
=
308495997
a=(1+\sqrt5)*inv(2) = 691504013,b=(1-\sqrt5)*inv(2)=308495997
a=(1+5)∗inv(2)=691504013,b=(1−5)∗inv(2)=308495997
代码:
原来的代码比赛的时候过了来着,赛后再交就TLE,又各种优化,各种预处理。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#include<bitset>
#include<map>
#include<unordered_map>
#include<set>
#define ui unsigned int
#define ll long long
#define llu unsigned ll
#define ld long double
#define pr make_pair
#define pb push_back
#define lc (cnt<<1)
#define rc (cnt<<1|1)
#define len(x) (t[(x)].r-t[(x)].l+1)
#define tmid ((l+r)>>1)
using namespace std;
const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const double dnf=1e18;
const int mod=1e9+9;
const double eps=1e-8;
const double pi=acos(-1.0);
const int hp=13331;
const int maxn=100100;
const int maxm=100100;
const int up=100000;
const int inv2=500000005;
const int sqrt5=383008016;
const int invsqrt5=276601605;
const int A=691504013;
const int B=308495997;
int fac[maxn],inv[maxn];
int mypow(int a,ll b)
{
b%=mod-1;
int ans=1;
while(b)
{
if(b&1) ans=1ll*ans*a%mod;
a=1ll*a*a%mod;
b>>=1;
}
return ans;
}
void init(void)
{
fac[0]=1;
for(int i=1;i<maxn;i++)
fac[i]=1ll*fac[i-1]*i%mod;
inv[maxn-1]=mypow(fac[maxn-1],mod-2);
for(int i=maxn-2;i>=0;i--)
inv[i]=1ll*inv[i+1]*(i+1)%mod;
}
int C(int n,int m)
{
return 1ll*fac[n]*inv[n-m]%mod*inv[m]%mod;
}
int main(void)
{
int tt;
scanf("%d",&tt);
init();
ll n,k,c,ans,res;
int q,tmp;
while(tt--)
{
scanf("%lld%lld%lld",&n,&c,&k);
ans=0;
q=mypow(mypow(A,k),c);
tmp=mypow(1ll*B*mypow(A,mod-2)%mod,c);
for(int i=0;i<=k;i++,q=1ll*q*tmp%mod)
{
if(q==1) res=n%mod*C(k,i)%mod;
else res=1ll*q*(mypow(q,n)-1)%mod*mypow(q-1,mod-2)%mod*C(k,i)%mod;
if(i&1) ans=(ans-res+mod)%mod;
else ans=(ans+res)%mod;
}
ans=ans*mypow(invsqrt5,k)%mod;
printf("%lld\n",ans);
}
return 0;
}