2020年杭电多校第一场 1005 Fibonacci Sum

题意

给定\(n,c\)\(k\),其中\(1\le n,c\le 10^{18},0\le k\le 100000\),求\(S=(F_0^k+F_{c}^k+F_{2c}^k+\dots+F_{nc}^k)mod~1000000009\)的值。

分析

看到这个题很多人过自己又不会做就去百度了下,发现有个几乎一样的原题大佬博客

这个题的不同之处就是多了个\(c\),只需要把等比数列求和的部分改一改,快速幂的部分欧拉降幂一下卡卡常就过了。

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
 
const int P=1000000009;
const int INV2=500000005;
const int SQRT5=383008016;
const int INVSQRT5=276601605;
const int A=691504013;
const int B=308495997;
const int PHI=1000000008;
 
const int N=100005;
 
ll n,c,K,nn,cc;
ll fac[N],inv[N];
ll pa[N],pb[N];
 
inline void Pre(int n){
  fac[0]=1; for (int i=1;i<=n;i++) fac[i]=fac[i-1]*i%P;
  inv[1]=1; for (int i=2;i<=n;i++) inv[i]=(P-P/i)*inv[P%i]%P;
  inv[0]=1; for (int i=1;i<=n;i++) inv[i]=inv[i]*inv[i-1]%P;
  pa[0]=1; for (int i=1;i<=n;i++) pa[i]=pa[i-1]*A%P;
  pb[0]=1; for (int i=1;i<=n;i++) pb[i]=pb[i-1]*B%P;
}
 
inline ll C(int n,int m){
  return fac[n]*inv[m]%P*inv[n-m]%P;
}
 
inline ll Pow(ll a,ll b){
  ll ret=1;
  for (;b;b>>=1,a=a*a%P)
    if (b&1)
      ret=ret*a%P;
  return ret;
}
 
inline ll Inv(ll x){
  return Pow(x,P-2);
}
 
inline void Solve(){
  ll Ans=0;
  for (int j=0;j<=K;j++){
    ll t=Pow(pa[K-j]*pb[j]%P,cc),tem;
    tem=t==1?n%P:t*(Pow(t,nn)-1+P)%P*Inv(t-1)%P;
    if (~j&1)
      Ans+=C(K,j)*tem%P,Ans%=P;
    else
      Ans+=P-C(K,j)*tem%P,Ans%=P;
  }
  Ans=Ans*Pow(INVSQRT5,K)%P;
  printf("%lld\n",Ans);
}

int main(){
  int T;
 // freopen("t.in","r",stdin);
 // freopen("t.out","w",stdout);
  Pre(100000);
  scanf("%d",&T);
  while (T--){
    scanf("%lld%lld%lld",&n,&c,&K);
    if(n<PHI) nn=n;
    else nn=n%PHI+PHI;
    if(c<PHI) cc=c;
    else cc=c%PHI+PHI;
    Solve();
  }
}
posted @ 2020-07-21 21:30  xyq0220  阅读(379)  评论(2编辑  收藏  举报