2020 Multi-University Training Contest 1---- HDU--6755、Fibonacci Sum(数论、二次剩余、二项式展开)

题目链接

题面:
在这里插入图片描述

题意:

∑ i = 0 n ( F c ∗ i ) k   m o d   1000000009 \sum_{i=0}^n(F_{c*i})^k\space mod \space1000000009 i=0n(Fci)k mod 1000000009
c , n < = 1 e 18 , k < = 1 e 5 c,n<=1e18,k<=1e5 c,n<=1e18,k<=1e5

题解:
首先认识到,1000000009 是一个质数,且 5 是模 1000000009 的二次剩余,即 x 2 = 5 ( m o d   1000000009 ) x^2=5(mod \space 1000000009) x2=5(mod 1000000009) 有解,那么我们解出 x 来就可以代替 5 \sqrt5 5 进行计算。

①斐波那契通项:
F n = 1 5 [ ( 1 + 5 2 ) n − ( 1 − 5 2 ) n ] F_n=\frac{1}{\sqrt5}[ (\frac{1+\sqrt5}{2})^n-(\frac{1-\sqrt5}{2})^n] Fn=5 1[(21+5 )n(215 )n]

②、
我 们 令 a = 1 + 5 2 , b = 1 − 5 2 ) 我们令 a=\frac{1+\sqrt5}{2},b=\frac{1-\sqrt5}{2}) a=21+5 ,b=215 )
有 F n = 1 5 ( a n − b n ) − − > F n k = ( 1 5 ) k ( a n − b n ) k 有F_n=\frac{1}{\sqrt5}(a^n-b^n)-->F_n^k=(\frac{1}{\sqrt5})^k(a^n-b^n)^k Fn=5 1(anbn)>Fnk=(5 1)k(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

化简后有:
( a n − b n ) 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 (a^n-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 (anbn)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

对于每一个 ( F c ∗ i ) k (F_{c*i})^k (Fci)k都这样表示,那么 ( − 1 ) r C k r (-1)^rC_k^r (1)rCkr项合并后为等比数列。(其中 i == 0 时, ( F c ∗ i ) k (F_{c*i})^k (Fci)k为0,可以忽略)。

等比数列 a 1 = a c ∗ ( k − r ) b c ∗ ( r ) , q = a c ∗ ( k − r ) b c ∗ ( r ) , n = n a_1=a^{c*(k-r)}b^{c*(r)},q=a^{c*(k-r)}b^{c*(r)},n=n a1=ac(kr)bc(r),q=ac(kr)bc(r),n=n
那么求和为, s u m = ( − 1 ) r C k r ∗ q ∗ ( q n − 1 ) q − 1 sum=(-1)^rC_k^r*\frac{q*(q^n-1)}{q-1} sum=(1)rCkrq1q(qn1)

q ≠ 1 q\neq1 q=1时,可以直接用公式计算
q = 1 q=1 q=1时,就是长度为 n 的首项为 1 的常数列。

③、
x 2 = 5 ( m o d   1000000009 ) x^2=5(mod \space 1000000009) x2=5(mod 1000000009)的一个解 x = 383008016 x=383008016 x=383008016
在模1e9+9的意义下, i n v ( 2 ) = 500000005 inv(2)=500000005 inv(2)=500000005
那么 a = ( 1 + 5 ) ∗ i n v ( 2 ) = 691504013 , b = ( 1 − 5 ) ∗ i n v ( 2 ) = 308495997 a=(1+\sqrt5)*inv(2) = 691504013,b=(1-\sqrt5)*inv(2)=308495997 a=(1+5 )inv(2)=691504013,b=(15 )inv(2)=308495997

代码:
原来的代码比赛的时候过了来着,赛后再交就TLE,又各种优化,各种预处理。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#include<bitset>
#include<map>
#include<unordered_map>
#include<set>
#define ui unsigned int
#define ll long long
#define llu unsigned ll
#define ld long double
#define pr make_pair
#define pb push_back
#define lc (cnt<<1)
#define rc (cnt<<1|1)
#define len(x)  (t[(x)].r-t[(x)].l+1)
#define tmid ((l+r)>>1)
using namespace std;

const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const double dnf=1e18;
const int mod=1e9+9;
const double eps=1e-8;
const double pi=acos(-1.0);
const int hp=13331;
const int maxn=100100;
const int maxm=100100;
const int up=100000;
const int inv2=500000005;
const int sqrt5=383008016;
const int invsqrt5=276601605;
const int A=691504013;
const int B=308495997;


int fac[maxn],inv[maxn];

int mypow(int a,ll b)
{
    b%=mod-1;
    int ans=1;
    while(b)
    {
        if(b&1) ans=1ll*ans*a%mod;
        a=1ll*a*a%mod;
        b>>=1;
    }
    return ans;
}

void init(void)
{
    fac[0]=1;
    for(int i=1;i<maxn;i++)
        fac[i]=1ll*fac[i-1]*i%mod;
    inv[maxn-1]=mypow(fac[maxn-1],mod-2);
    for(int i=maxn-2;i>=0;i--)
        inv[i]=1ll*inv[i+1]*(i+1)%mod;
}

int C(int n,int m)
{
    return 1ll*fac[n]*inv[n-m]%mod*inv[m]%mod;
}

int main(void)
{
    int tt;
    scanf("%d",&tt);
    init();
    ll n,k,c,ans,res;
    int q,tmp;
    while(tt--)
    {
        scanf("%lld%lld%lld",&n,&c,&k);
        ans=0;
        q=mypow(mypow(A,k),c);
        tmp=mypow(1ll*B*mypow(A,mod-2)%mod,c);
        for(int i=0;i<=k;i++,q=1ll*q*tmp%mod)
        {
            if(q==1) res=n%mod*C(k,i)%mod;
            else res=1ll*q*(mypow(q,n)-1)%mod*mypow(q-1,mod-2)%mod*C(k,i)%mod;
            if(i&1) ans=(ans-res+mod)%mod;
            else ans=(ans+res)%mod;
        }
        ans=ans*mypow(invsqrt5,k)%mod;
        printf("%lld\n",ans);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值