HDU6755.Fibonacci Sum

HDU6755.Fibonacci Sum(二次剩余)

思路: f i b n a c c i fibnacci fibnacci二次剩余转等比数列求和。

f i b o n a c c i fibonacci fibonacci公式: F n = 1 5 × [ ( 5 + 1 2 ) n − ( 5 − 1 2 ) n ] F_n=\dfrac{1}{\sqrt{5}}\times [(\dfrac{\sqrt{5}+1}{2})^n-(\dfrac{\sqrt{5}-1}{2})^n] Fn=5 1×[(25 +1)n(25 1)n]

a = ( 5 + 1 2 ) n , b = ( 5 − 1 2 ) n a=(\dfrac{\sqrt{5}+1}{2})^n,b=(\dfrac{\sqrt{5}-1}{2})^n a=(25 +1)n,b=(25 1)n

1 5 ( m o d p ) = t m p \dfrac{1}{\sqrt{5}}\pmod{p}=tmp 5 1(modp)=tmp

F n k = t m p k × ( a n − b n ) k F_n^k=tmp^k\times (a^n-b^n)^k Fnk=tmpk×(anbn)k

右边展开得

∑ i = 0 k C k i ( − 1 ) i [ a ( k − i ) b i ] n \sum\limits_{i=0}^kC_k^i (-1)^i[a^{(k-i)}b^i]^n i=0kCki(1)i[a(ki)bi]n

同理

F n − 1 k = t m p k × ( a n − 1 − b n − 1 ) k = t m p k × ∑ i = 0 k C k i ( − 1 ) i [ a k − i b i ] n − 1 F_{n-1}^k=tmp^k\times(a^{n-1}-b^{n-1})^k\\=tmp^k\times \sum\limits_{i=0}^kC_k^i (-1)^i[a^{k-i}b^i]^{n-1} Fn1k=tmpk×(an1bn1)k=tmpk×i=0kCki(1)i[akibi]n1

考虑将含 C k i ( − 1 ) i C_k^i(-1)^i Cki(1)i的所有项合并。

∵ F 0 = 0 \because F_0=0 F0=0

∴ ∑ i = 0 n F i = ∑ i = 1 n F i \therefore \sum\limits_{i=0}^n F_i=\sum\limits_{i=1}^n F_i i=0nFi=i=1nFi

= t m p k × ∑ i = 0 k ( − 1 ) i C k i × ( a k − i b i + ( a k − i b i ) 2 + ( a k − i b i ) 3 ⋯ + ( a k − i b i ) n ) =tmp^k\times\sum\limits_{i=0}^k(-1)^iC_k^i \times(a^{k-i}b^i+(a^{k-i}b^i)^2+(a^{k-i}b^i)^3\dots+(a^{k-i}b^i)^n) =tmpk×i=0k(1)iCki×(akibi+(akibi)2+(akibi)3+(akibi)n)

( a k − i b i ) = x (a^{k-i}b^i)=x (akibi)=x

= t m p k × ∑ i = 0 k ( − 1 ) i C k i × x ( x n − 1 ) x − 1 =tmp^k\times \sum\limits_{i=0}^k(-1)^iC_k^i \times \dfrac{x(x^n-1)}{x-1} =tmpk×i=0k(1)iCki×x1x(xn1)

x = 1 x=1 x=1特判,直接求和为 n n n

F i F_i Fi变为 F i c F_{ic} Fic,公式变为: t m p k × ∑ i = 0 k ( − 1 ) i C k i × x ( x n − 1 ) x − 1 , x = ( a k − i b i ) c tmp^k\times \sum\limits_{i=0}^k(-1)^iC_k^i \times \dfrac{x(x^n-1)}{x-1},x=(a^{k-i}b^i)^c tmpk×i=0k(1)iCki×x1x(xn1),x=(akibi)c

然后快速幂加逆元搞下就出来了。

注意优化常数:如 x x x只用求一次,后面递推即可。

然后还有一个优化是:

根据欧拉定理: x y ( m o d p ) = x y ( m o d p − 1 ) ( m o d p ) x^y\pmod{p}=x^{y\pmod{p-1}}\pmod{p} xy(modp)=xy(modp1)(modp)

x , p x,p x,p互质时可得。

(该优化的证明已给出,下面是传送门.)
传送门

此外 t m p tmp tmp可以根据:二次剩余知识 x 2 = 5 ( m o d p ) x^2=5\pmod{p} x2=5(modp)
搞出 x = 383008016 x=383008016 x=383008016,
然后可以求出 a , b a,b a,b在模 p p p下的值为:
691504013 , 308495997 691504013,308495997 691504013,308495997.
以上有时间再证明…
时间复杂度: O ( k l o g n ) O(klogn) O(klogn)

但是为毛实测跑这么慢 1.5 s 1.5s 1.5s

#include
using namespace std;
typedef long long ll;
const int N=1e5+5,M=2e4+5,inf=0x3f3f3f3f;
const ll mod=1e9+9;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair
#define fi first
#define se second
#define pb push_back
ll ksm(ll a,ll n){
	ll ans=1;
	while(n){
		if(n&1) ans=ans*a%mod;
		a=a*a%mod;
		n>>=1;
	}
	return ans;
}
ll n,c,k,fac[N],inv[N];
void pre(){
	int n=1e5;fac[0]=inv[0]=1;
	for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
	inv[n]=ksm(fac[n],mod-2);
	for(int i=n-1;i>=1;i--) inv[i]=inv[i+1]*(i+1)%mod;
}
ll C(ll n,ll m){
	return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
ll fun(ll n,ll c,ll k){
	ll ans=0;
	ll a=ksm(691504013,c%(mod - 1)),b=ksm(308495997,c%(mod - 1));
	ll A=1,B=ksm(b,k),invB=ksm(b,mod-2);
	for(int i=0;i<=k;i++){
		ll x=A*B%mod;
		ll y=C(k,i),sum;
		if(x==1) sum=n%mod;
		else sum=x*(ksm(x,n%(mod-1))-1+mod)%mod*ksm(x-1,mod-2)%mod;
		if((k-i)&1) ans-=sum*y%mod;
		else ans+=sum*y%mod;
		ans%=mod;
		A=A*a%mod,B=B*invB%mod;
	}
	ll tmp=ksm(383008016,mod-2);
    ans=ans*ksm(tmp,k)% mod;
    return (ans%mod+mod)%mod;
}
int main(){
	pre();
	int t;
	scanf("%d",&t);
	while(t--){
	scanf("%lld%lld%lld",&n,&c,&k);
	printf("%lld\n",fun(n,c,k));
	}
	return 0;
}

你可能感兴趣的:(二次剩余,数论)