[数学记录]51nod1236 序列求和 V3
command_block · · 个人记录
题意 : 设
给出
答案对
多组数据,
考虑斐波那契数列的通项公式 :
方便起见,设
附 :
后半部等比数列求和即可,复杂度
#include<algorithm>
#include<cstdio>
#define ll long long
#define MaxN 100500
using namespace std;
int mod=1000000009,w=383008016;
ll powM(ll a,int t=mod-2){
ll ret=1;
while(t){
if (t&1)ret=ret*a%mod;
a=a*a%mod;t>>=1;
}return ret;
}
ll fac[MaxN],ifac[MaxN],pwa[MaxN],pwb[MaxN];
void Init(int n)
{
fac[0]=1;
for (int i=1;i<=n;i++)
fac[i]=fac[i-1]*i%mod;
ifac[n]=powM(fac[n]);
for (int i=n;i;i--)
ifac[i-1]=ifac[i]*i%mod;
ll a=(1+w)*powM(2)%mod
,b=(1-w)*powM(2)%mod;
pwa[0]=pwb[0]=1;
for (int i=1;i<=n;i++){
pwa[i]=pwa[i-1]*a%mod;
pwb[i]=pwb[i-1]*b%mod;
}
}
ll S(ll a,ll n){
if (a==1)return n%mod;
return a*(powM(a,n%(mod-1))-1)%mod*powM(a-1)%mod;
}
void solve(ll n,int k)
{
ll ans=0;
for (int i=0;i<=k;i++){
ll buf=ifac[i]*ifac[k-i]%mod*S(pwa[i]*pwb[k-i]%mod,n);
if ((k-i)&1)ans=(ans-buf)%mod;
else ans=(ans+buf)%mod;
}ans=(ans+mod)%mod;
printf("%lld\n",ans*fac[k]%mod*powM(w,mod-1-k)%mod);
}
ll n[15];int T,k[15],lim;
int main()
{
scanf("%d",&T);
for (int i=1;i<=T;i++){
scanf("%lld%d",&n[i],&k[i]);
lim=max(lim,k[i]);
}Init(lim);
for (int i=1;i<=T;i++)
solve(n[i],k[i]);
return 0;
}