数论(二次剩余 + 二项式定理 + 斐波那契数列) - Fibonacci Sum - HDU 6755
2020 Multi-University Training Contest 1 1005
题意:
斐
波
那
契
数
列
:
斐波那契数列:
斐 波 那 契 数 列 :
{
F
0
=
0
,
F
1
=
1
F
n
=
F
n
−
1
+
F
n
−
2
(
n
>
1
)
\begin{cases}F_0=0,F_1=1\\\\F_n=F_{n-1}+F_{n-2}(n>1)\end{cases}
⎩ ⎪ ⎨ ⎪ ⎧ F 0 = 0 , F 1 = 1 F n = F n − 1 + F n − 2 ( n > 1 )
给
定
正
整
数
N
、
C
、
K
,
计
算
:
给定正整数N、C、K,计算:
给 定 正 整 数 N 、 C 、 K , 计 算 :
(
F
0
)
K
+
(
F
C
)
K
+
(
F
2
C
)
K
+
.
.
.
+
(
F
N
C
)
K
(F_0)^K+(F_{C})^K+(F_{2C})^K+...+(F_{NC})^K
( F 0 ) K + ( F C ) K + ( F 2 C ) K + . . . + ( F N C ) K
答
案
对
1
0
9
+
9
取
模
。
答案对10^9+9取模。
答 案 对 1 0 9 + 9 取 模 。
Input
The first line contains an integer T (1≤T≤200), denoting the number of test cases. Each test case contains three space separated integers in the order: N, C, K (1≤N,C≤1018 ,1≤K≤105 ).
Output
For each test case, output a single line containing the answer.
Sample Input
2
5 1 1
2 1 2
Sample Output
12
2
分析:
本
题
或
许
改
编
自
:
本题或许改编自:
本 题 或 许 改 编 自 : Power of Fibonacci - ZOJ 3774
斐
波
那
契
数
列
的
通
项
公
式
:
斐波那契数列的通项公式:
斐 波 那 契 数 列 的 通 项 公 式 :
F
n
=
1
5
[
(
1
+
5
2
)
n
−
(
1
−
5
2
)
n
]
F_n=\frac{1}{\sqrt{5}}[(\frac{1+\sqrt{5}}{2})^n-(\frac{1-\sqrt{5}}{2})^n]
F n = 5
1 [ ( 2 1 + 5
) n − ( 2 1 − 5
) n ]
首
先
,
5
是
模
数
1
0
9
的
首先,5是模数10^9的
首 先 , 5 是 模 数 1 0 9 的 二次剩余
即
用
满
足
:
x
2
≡
5
m
o
d
1
0
9
+
9
的
x
来
代
替
5
m
o
d
1
0
9
+
9
。
即用满足:x^2≡5\ mod\ 10^9+9\ 的x来代替\ \sqrt{5}\ mod\ 10^9+9。
即 用 满 足 : x 2 ≡ 5 m o d 1 0 9 + 9 的 x 来 代 替 5
m o d 1 0 9 + 9 。
计
算
得
到
一
个
满
足
条
件
的
x
=
383008016
计算得到一个满足条件的x=383008016
计 算 得 到 一 个 满 足 条 件 的 x = 3 8 3 0 0 8 0 1 6
则
:
则:
则 :
1
5
≡
276601605
(
m
o
d
1
0
9
+
9
)
,
1
+
5
2
≡
691504013
(
m
o
d
1
0
9
+
9
)
,
1
−
5
2
≡
308495997
(
m
o
d
1
0
9
+
9
)
\frac{1}{\sqrt{5}}≡276601605\ (mod\ 10^9+9),\frac{1+\sqrt{5}}{2}≡691504013\ (mod\ 10^9+9),\frac{1-\sqrt{5}}{2}≡308495997\ (mod\ 10^9+9)
5
1 ≡ 2 7 6 6 0 1 6 0 5 ( m o d 1 0 9 + 9 ) , 2 1 + 5
≡ 6 9 1 5 0 4 0 1 3 ( m o d 1 0 9 + 9 ) , 2 1 − 5
≡ 3 0 8 4 9 5 9 9 7 ( m o d 1 0 9 + 9 )
令
D
=
276601605
,
a
=
691504013
,
b
=
308495997
,
令D=276601605,a=691504013,b=308495997,
令 D = 2 7 6 6 0 1 6 0 5 , a = 6 9 1 5 0 4 0 1 3 , b = 3 0 8 4 9 5 9 9 7 ,
原
式
等
价
于
对
数
列
:
原式等价于对数列:
原 式 等 价 于 对 数 列 :
F
n
k
=
D
k
(
a
n
−
b
n
)
k
F_n^k=D^k(a^n-b^n)^k
F n k = D k ( a n − b n ) k
的
部
分
项
求
和
并
对
1
0
9
取
模
。
的部分项求和并对10^9取模。
的 部 分 项 求 和 并 对 1 0 9 取 模 。
观
察
(
a
n
−
b
n
)
k
,
根
据
二
项
式
展
开
:
观察(a^n-b^n)^k,根据二项式展开:
观 察 ( a n − b n ) k , 根 据 二 项 式 展 开 :
(
a
n
−
b
n
)
k
=
C
k
0
(
a
n
)
k
(
b
n
)
0
(
−
1
)
0
+
C
k
1
(
a
n
)
k
−
1
(
b
n
)
1
(
−
1
)
1
+
.
.
.
+
C
k
r
(
a
n
)
k
−
r
(
b
n
)
r
(
−
1
)
r
+
.
.
.
+
C
k
k
(
a
n
)
0
(
b
n
)
k
(
−
1
)
k
(a^n-b^n)^k=C_k^0(a^n)^k(b^n)^0(-1)^0+C_k^1(a^n)^{k-1}(b^n)^1(-1)^1+...+C_k^r(a^n)^{k-r}(b^n)^r(-1)^r+...+C_k^k(a^n)^0(b^n)^k(-1)^k
( a n − b n ) k = C k 0 ( a n ) k ( b n ) 0 ( − 1 ) 0 + C k 1 ( a n ) k − 1 ( b n ) 1 ( − 1 ) 1 + . . . + C k r ( a n ) k − r ( b n ) r ( − 1 ) r + . . . + C k k ( a n ) 0 ( b n ) k ( − 1 ) k
记
(
−
1
)
r
C
k
r
=
M
r
,
S
n
r
=
(
a
n
)
k
−
r
(
b
n
)
r
,
上
式
转
化
为
:
记(-1)^rC_k^r=M_r,S_{nr}=(a^{n})^{k-r}(b^{n})^r,上式转化为:
记 ( − 1 ) r C k r = M r , S n r = ( a n ) k − r ( b n ) r , 上 式 转 化 为 :
(
a
n
−
b
n
)
k
=
M
0
S
n
0
+
M
1
S
n
1
+
.
.
.
+
M
r
S
n
r
+
.
.
.
+
M
k
S
n
k
(a^n-b^n)^k=M_0S_{n0}+M_1S_{n1}+...+M_rS_{nr}+...+M_kS_{nk}
( a n − b n ) k = M 0 S n 0 + M 1 S n 1 + . . . + M r S n r + . . . + M k S n k
则
:
则:
则 :
F
n
k
=
D
k
(
M
0
S
n
0
+
M
1
S
n
1
+
.
.
.
+
M
k
S
n
k
)
F_{n}^k=D^k(M_0S_{n0}+M_1S_{n1}+...+M_kS_{nk})
F n k = D k ( M 0 S n 0 + M 1 S n 1 + . . . + M k S n k )
不
论
n
取
何
值
,
S
n
r
前
的
系
数
均
相
同
,
为
M
r
,
不论n取何值,S_{nr}前的系数均相同,为M_r,
不 论 n 取 何 值 , S n r 前 的 系 数 均 相 同 , 为 M r ,
原
式
等
价
于
:
原式等价于:
原 式 等 价 于 :
(
F
0
)
k
+
(
F
C
)
k
+
(
F
2
C
)
k
+
.
.
.
+
(
F
N
C
)
k
=
(
F
C
)
k
+
(
F
2
C
)
k
+
.
.
.
+
(
F
N
C
)
k
(F_0)^k+(F_{C})^k+(F_{2C})^k+...+(F_{NC})^k=(F_{C})^k+(F_{2C})^k+...+(F_{NC})^k
( F 0 ) k + ( F C ) k + ( F 2 C ) k + . . . + ( F N C ) k = ( F C ) k + ( F 2 C ) k + . . . + ( F N C ) k
=
M
0
(
∑
i
=
1
N
S
(
i
⋅
C
)
0
)
+
M
1
(
∑
i
=
1
N
S
(
i
⋅
C
)
1
)
+
.
.
.
+
M
k
(
∑
i
=
1
N
S
(
i
⋅
C
)
k
)
=M_0(\sum_{i=1}^NS_{(i·C)0})+M_1(\sum_{i=1}^NS_{(i·C)1})+...+M_k(\sum_{i=1}^NS_{(i·C)k})
= M 0 ( i = 1 ∑ N S ( i ⋅ C ) 0 ) + M 1 ( i = 1 ∑ N S ( i ⋅ C ) 1 ) + . . . + M k ( i = 1 ∑ N S ( i ⋅ C ) k )
本
题
k
≤
1
0
5
,
可
以
从
0
到
k
枚
举
r
,
而
当
r
为
常
数
时
,
S
i
是
一
个
关
于
i
的
等
比
数
列
,
本题k≤10^5,可以从0到k枚举r,而当r为常数时,S_i是一个关于i的等比数列,
本 题 k ≤ 1 0 5 , 可 以 从 0 到 k 枚 举 r , 而 当 r 为 常 数 时 , S i 是 一 个 关 于 i 的 等 比 数 列 ,
公
比
q
=
S
i
+
1
S
i
=
(
a
i
+
1
)
k
−
r
(
b
i
+
1
)
r
(
a
i
)
k
−
r
(
b
i
)
r
=
a
(
k
−
r
)
b
r
公比\ q=\frac{S_{i+1}}{S_{i}}=\frac{(a^{i+1})^{k-r}(b^{i+1})^r}{(a^{i})^{k-r}(b^{i})^r}=a^{(k-r)}b^{r}
公 比 q = S i S i + 1 = ( a i ) k − r ( b i ) r ( a i + 1 ) k − r ( b i + 1 ) r = a ( k − r ) b r
则
数
列
G
i
=
S
C
i
的
公
比
为
Q
=
q
C
=
a
C
(
k
−
r
)
b
C
r
,
首
项
为
G
1
=
S
C
=
a
C
(
k
−
r
)
b
C
r
=
Q
则数列G_i=S_{Ci}的公比为Q=q^C=a^{C(k-r)}b^{Cr},首项为G_1=S_{C}=a^{C(k-r)}b^{Cr}=Q
则 数 列 G i = S C i 的 公 比 为 Q = q C = a C ( k − r ) b C r , 首 项 为 G 1 = S C = a C ( k − r ) b C r = Q
等
比
数
列
G
i
求
和
:
∑
i
=
1
N
G
i
=
Q
(
Q
n
−
1
)
Q
−
1
等比数列G_i求和:\sum_{i=1}^NG_i=\frac{Q(Q^n-1)}{Q-1}
等 比 数 列 G i 求 和 : ∑ i = 1 N G i = Q − 1 Q ( Q n − 1 )
因
此
,
我
们
可
以
通
过
枚
举
r
对
M
r
(
∑
i
=
1
N
G
i
)
求
和
,
即
计
算
:
因此,我们可以通过枚举r对M_r(\sum_{i=1}^NG_i)求和,即计算:
因 此 , 我 们 可 以 通 过 枚 举 r 对 M r ( ∑ i = 1 N G i ) 求 和 , 即 计 算 :
∑
r
=
0
k
M
r
(
∑
i
=
1
N
G
i
)
=
∑
r
=
0
k
(
−
1
)
r
C
k
r
(
Q
(
Q
n
−
1
)
Q
−
1
)
,
其
中
Q
=
a
C
(
k
−
r
)
b
C
r
。
\sum_{r=0}^kM_r(\sum_{i=1}^NG_i)=\sum_{r=0}^k(-1)^rC_k^r(\frac{Q(Q^n-1)}{Q-1}),其中Q=a^{C(k-r)}b^{Cr}。
r = 0 ∑ k M r ( i = 1 ∑ N G i ) = r = 0 ∑ k ( − 1 ) r C k r ( Q − 1 Q ( Q n − 1 ) ) , 其 中 Q = a C ( k − r ) b C r 。
注意:
Q
=
1
时
,
∑
i
=
1
N
G
i
=
N
,
直
接
累
加
(
−
1
)
r
C
k
r
×
N
即
可
。
Q=1时,\sum_{i=1}^NG_i=N,直接累加(-1)^rC_k^r×N即可。
Q = 1 时 , ∑ i = 1 N G i = N , 直 接 累 加 ( − 1 ) r C k r × N 即 可 。
具体细节:
①
、
求
组
合
数
C
r
k
可
以
通
过
定
义
,
C
k
r
=
k
!
r
!
⋅
(
k
−
r
)
!
来
解
决
,
需
要
预
处
理
k
!
和
对
应
的
逆
元
。
①、求组合数C_r^k可以通过定义,C_k^r=\frac{k!}{r!·(k-r)!}来解决,需要预处理k!和对应的逆元。
① 、 求 组 合 数 C r k 可 以 通 过 定 义 , C k r = r ! ⋅ ( k − r ) ! k ! 来 解 决 , 需 要 预 处 理 k ! 和 对 应 的 逆 元 。
②
、
将
a
、
b
带
入
,
对
枚
举
的
每
一
个
r
,
用
快
速
幂
求
具
体
的
Q
。
②、将a、b带入,对枚举的每一个r,用快速幂求具体的Q。
② 、 将 a 、 b 带 入 , 对 枚 举 的 每 一 个 r , 用 快 速 幂 求 具 体 的 Q 。
优化:
本
题
时
间
限
制
卡
的
非
常
紧
,
需
要
对
一
些
计
算
做
优
化
:
本题时间限制卡的非常紧,需要对一些计算做优化:
本 题 时 间 限 制 卡 的 非 常 紧 , 需 要 对 一 些 计 算 做 优 化 :
观
察
相
邻
两
项
的
公
比
:
观察相邻两项的公比:
观 察 相 邻 两 项 的 公 比 :
Q
=
a
C
(
k
−
r
)
b
C
r
①
\qquad Q=a^{C(k-r)}b^{Cr}\qquad\qquad\ \ \ ①
Q = a C ( k − r ) b C r ①
Q
=
a
C
(
k
−
(
r
+
1
)
)
b
C
(
r
+
1
)
②
\qquad Q=a^{C(k-(r+1))}b^{C(r+1)}\qquad②
Q = a C ( k − ( r + 1 ) ) b C ( r + 1 ) ②
发
现
,
①
×
−
(
b
C
a
C
)
=
②
\qquad发现,①×-(\frac{b^C}{a^C})=②
发 现 , ① × − ( a C b C ) = ②
因
此
,
我
们
可
以
通
过
递
归
由
①
推
②
,
减
少
快
速
幂
的
计
算
。
\qquad因此,我们可以通过递归由①推②,减少快速幂的计算。
因 此 , 我 们 可 以 通 过 递 归 由 ① 推 ② , 减 少 快 速 幂 的 计 算 。
费
马
小
定
理
:
模
数
p
=
1
0
9
+
9
是
质
数
,
可
以
通
过
费
马
小
定
理
a
p
−
1
≡
1
(
m
o
d
p
)
,
优
化
快
速
幂
。
费马小定理:模数p=10^9+9是质数,可以通过费马小定理a^{p-1}≡1(mod\ p),优化快速幂。
费 马 小 定 理 : 模 数 p = 1 0 9 + 9 是 质 数 , 可 以 通 过 费 马 小 定 理 a p − 1 ≡ 1 ( m o d p ) , 优 化 快 速 幂 。
时间复杂度:
O
(
T
k
l
o
g
(
m
o
d
)
)
.
O(Tklog(mod)).
O ( T k l o g ( m o d ) ) .
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
const int N= 1e5 , mod= 1e9 + 9 ;
const int a= 691504013 , b= 308495997 , D= 276601605 ;
int fac[ N+ 10 ] , inv[ N+ 10 ] ;
int quick_pow ( ll a, ll b, int mod)
{
int res= 1 ;
a% = mod;
while ( b)
{
if ( b& 1 ) res= ( ll) res* a% mod;
a= a* a% mod;
b>>= 1 ;
}
return res;
}
void Init ( )
{
fac[ 0 ] = 1 ;
for ( int i= 1 ; i<= N; i++ ) fac[ i] = ( ll) fac[ i- 1 ] * i% mod;
for ( int i= 0 ; i<= N; i++ ) inv[ i] = quick_pow ( fac[ i] , mod- 2 , mod) ;
}
int INV ( int x)
{
return quick_pow ( x, mod- 2 , mod) ;
}
int C ( int n, int m)
{
if ( n< m) return 0 ;
return ( ll) fac[ n] * inv[ m] % mod* inv[ n- m] % mod;
}
int Sum ( ll n, ll c, int k)
{
ll ans= 0 ;
int ac= quick_pow ( a, c% ( mod- 1 ) , mod) ,
bc= quick_pow ( b, c% ( mod- 1 ) , mod) ;
int an= quick_pow ( ac, k, mod) ,
bn= 1 ;
int ainv= INV ( ac) ;
for ( int r= 0 ; r<= k; r++ )
{
int Q= ( ll) an* bn% mod, S;
int Ckr= C ( k, r) ;
if ( r& 1 ) Ckr= - Ckr;
if ( Q== 1 ) S= n% mod;
else S= ( ll) Q* ( quick_pow ( Q, n% ( mod- 1 ) , mod) - 1 ) % mod* INV ( Q- 1 ) % mod;
S= ( ll) Ckr* S% mod;
ans+ = S;
an= ( ll) an* ainv% mod;
bn= ( ll) bn* bc% mod;
}
ans= ( ans% mod+ mod) * quick_pow ( D, k, mod) % mod;
return ans;
}
int main ( )
{
Init ( ) ;
int T, k;
ll n, c;
cin>> T;
while ( T-- )
{
scanf ( "%lld%lld%d" , & n, & c, & k) ;
printf ( "%d\n" , Sum ( n, c, k) ) ;
}
return 0 ;
}