[斐波那契幂和+二次剩余]2020hdu多校 6755 Fibonacci Sum

题目

在这里插入图片描述
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6755

思路

前置知识:斐波那契的幂和
该博客是对F1^k ~ Fn^k 的和的讲解 谢谢大佬
该题具体思路:大佬博客
斐波那契的幂和可以化为二项式相加
用二次剩余求出sqrt(5) 计算出a,b的值
预处理组合数需要的阶乘与逆元 、a、b的次方
欧拉降幂优化
最后运用推出的来的公式算出来就好了

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int mod= 1e9+9,a=691504013,b=308495997,d=276601605;
inline int quick_pow(int a1,int b1){
	int res=1;
	while(b1){
		if(b1&1){
			res=(res*a1)%mod;
		}
		a1=a1*a1%mod;
		b1>>=1;
	}
	return res;
}
int c[100010],invc[100010],ack[100010],bck[100010];
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int t;
	cin>>t;
	c[0]=1;
	for(int i=1;i<=100000;i++){
		c[i]=c[i-1]*i%mod;
	}
	invc[100000]=quick_pow(c[100000],mod-2);
	for(int i=100000-1;i>=0;i--){
		invc[i]=invc[i+1]*(i+1)%mod;
	}
	while(t--){
		int n,c1,k;
		cin>>n>>c1>>k;
		int ac=quick_pow(a,c1%(mod-1));
		int bc=quick_pow(b,c1%(mod-1));
		ack[0]=1,bck[0]=1;
		for(int i=1;i<=k;i++){
			ack[i]=ack[i-1]*ac%mod;
			bck[i]=bck[i-1]*bc%mod;
		} 
		int ans=0;
		for(int i=0;i<=k;i++){
			int sum=c[k]*invc[i]%mod*invc[k-i]%mod;
			if(i&1) sum=mod-sum;
			int t=ack[k-i]*bck[i]%mod;
			if(t==1) ans=(ans+(n)%mod*sum)%mod;
			else{
				ans=(ans+sum*(t*(quick_pow(t,(n)%(mod-1))-1ll+mod)%mod*quick_pow(t-1,mod-2)%mod))%mod;
			}
		}
		ans=ans*quick_pow(d,k%(mod-1))%mod;	
		cout<<ans<<endl;	
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/kosf_/article/details/107591496