hdu6755 Fibonacci Sum(二项式定理)

题目链接:点击这里

题目大意:
给定正整数 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=0nF(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)=5 1((21+5 )n(215 )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(215 )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=215
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(anbn)k
( a n − b n ) k (a^n-b^n)^k (anbn)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 (anbn)k=Ck0(an)k(bn)0+Ck1(an)k1(bn)1+...+Ckr(an)kr(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)k1(bn)1+...+(1)rCkr(an)kr(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(ak1)n(b1)n+...+(1)rCkr(akr)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 akrbr 的等比数列,合并后的和为 ( − 1 ) r C k r t ( 1 − t n ) 1 − t (-1)^rC_k^r\frac {t(1-t^n)}{1-t} (1)rCkr1tt(1tn) 其中 t = a k − r b r t=a^{k-r}b^r t=akrbr
所以有:
∑ 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=0nF(i)=(5 )k1i=0k(1)iCki1tt(1tn)(t=akibi)
有了这个式子以后我们就可以更轻松的解决所求问题了,此时我们加上 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(215 )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=0nF(cn)k=(5 )k1i=0k(1)iCki1tt(1tn)(t=(akibi)c)

接下来便是计算问题了:
我们首先求出 5 5 5 的二次剩余即 x 2 ≡ 5 m o d    1 e 9 + 9 x^2\equiv5\mod 1e9+9 x25mod1e9+9 的解是 383008016 383008016 383008016
然后再用逆元计算出 a , b a,b a,b 的值, a = 691504013 , b = 308495997 a=691504013,b=308495997 a=691504013,b=308495997
这个题还需要卡一下常数,卡常用的方法:

  1. 欧拉降幂: 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%(p1)modp
  2. 不提前处理 a k − i b i ) c a^{k-i}b^i)^c akibi)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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值