题解 CF392C Yet Another Number Sequence

题解 CF392C Yet Another Number Sequence

题目链接

题意描述

\(A_i=F_i*i^k\),求\(\sum\limits_{i=1}^{n}A_i\)\(F_i\) 指斐波那契数列第 \(i\) 项)
\(n\leq 10^{17},k\leq 40\)

\(n\)很大,\(k\)很小,显然矩阵快速幂。

根据二项式定理,我们得到:

\[\begin{align*}A_i&=F_i\times i^k\\&=(F_{i-1}+F_{i-2})\times i^k\\&=F_{i-1}\times i^k+F_{i-2}\times i^k\\&=F_{i-1}\times [(i-1)+1]^k+F_{i-2}\times [(i-2)+2]^k\\&=F_{i-1}\times\sum\limits_{j=0}^k\binom{k}{j}\times (i-1)^j+F_{i-2}\times \sum\limits_{j=0}^k\binom{k}{j}\times (i-2)^j\times 2^{k-j}\end{align*} \]

交换求和顺序:

\[\begin{align*}A_i&=\sum\limits_{j=0}^k\binom{k}{j}\times F_{i-1}\times (i-1)^j+\sum\limits_{j=0}^k\binom{k}{j}\times 2^{k-j}\times F_{i-2}\times (i-2)^j\end{align*} \]

考虑将\(F_i\times i^{0\sim k},F_{i+1}\times i^{0\sim k}\)和前缀和\(Sum_i\)放入一个列向量,即:

\[\begin{bmatrix}F_i\times i_0\\F_i\times i_1\\\vdots\\F_i\times i_k\\F_{i+1}\times (i+1)^0\\F_{i+1}\times (i+1)^1\\\vdots\\F_{i+1}\times (i+1)^k\\Sum_i\end{bmatrix} \]

得到转移矩阵:

\[\begin{bmatrix}0&0&0&\cdots&0&1&0&\cdots&0&0&0\\0&0&0&\cdots&0&1&0&\cdots&0&0&0\\\vdots&\vdots&\vdots&\ddots&\vdots&\vdots&\vdots&\ddots&\vdots&\vdots&\vdots\\0&0&0&\cdots&0&0&0&\cdots&0&1&0\\2^0\times\binom{0}{0}&0&0&\cdots&0&\binom{0}{0}&0&\cdots&0&0&0\\2^1\times\binom{1}{0}&2^0\times\binom{1}{1}&0&\cdots&0&\binom{1}{0}&\binom{1}{1}&\cdots&0&0&0\\\vdots&\vdots&\vdots&\ddots&\vdots&\vdots&\vdots&\ddots&\vdots&\vdots&\vdots\\2^k\times\binom{k}{0}&2^{k-1}\times\binom{k}{1}&2^{k-2}\times\binom{k}{2}&\cdots&2^0\times\binom{k}{k}&\binom{k}{0}&\binom{k}{1}&\cdots&\binom{k}{k-1}&\binom{k}{k}&0\\2^k\times\binom{k}{0}&2^{k-1}\times\binom{k}{1}&2^{k-2}\times\binom{k}{2}&\cdots&2^0\times\binom{k}{k}&\binom{k}{0}&\binom{k}{1}&\cdots&\binom{k}{k-1}&\binom{k}{k}&1\end{bmatrix}\times\begin{bmatrix}F_{i-1}\times {i-1}^0\\F_{i-1}\times {i-1}^1\\\vdots\\F_{i-1}\times {i-1}^k\\F_i\times i^0\\F_i\times i^1\\\vdots\\F_i\times i^k\\Sum_i\end{bmatrix}=\begin{bmatrix}F_i\times i^0\\F_i\times i^1\\\vdots\\F_i\times i^k\\F_{i+1}\times {i+1}^0\\F_{i+1}\times {i+1}^1\\\vdots\\F_{i+1}\times {i+1}^k\\Sum_i\end{bmatrix} \]

初始矩阵:

\[\begin{bmatrix}F_0\times 0^0\\F_0\times 0^1\\\vdots\\F_0\times 0^k\\F_1\times i^0\\F_1\times 1\\\vdots\\F_1\times 1^k\\Sum_1\end{bmatrix}=\begin{bmatrix}1\\0\\\vdots\\0\\1\\1\\\vdots\\1\\1\end{bmatrix} \]

直接转移即可。

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define inf 0x3f3f3f3f
#define N 90
#define ls k<<1
#define rs k<<1|1
#define mid ((l+r)>>1)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define pii pair<int,int>
#define il inline
#define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout)
using namespace std;
il int read(){
    int w=0,h=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')h=-h;ch=getchar();}
    while(ch>='0'&&ch<='9'){w=w*10+ch-'0';ch=getchar();}
    return w*h;
}
const int mod=1e9+7;
int n,K;
int Fac[N+5],Pw[N+5];
int qpow(int b,int k){
    int s=1;
    while(k){
        if(k&1)s=s*b%mod;
        b=b*b%mod;
        k>>=1;
    }
    return s;
}
int inv(int a){return qpow(a,mod-2);}
int C(int n,int m){return Fac[n]*inv(Fac[m])%mod*inv(Fac[n-m])%mod;}
struct Matrix{
    int G[N+5][N+5];
    Matrix operator*(const Matrix&b)const{
        Matrix c;
        for(int i=1;i<=N;i++)
            for(int j=1;j<=N;j++){
                c.G[i][j]=0;
                for(int k=1;k<=N;k++)
                    c.G[i][j]=(c.G[i][j]+G[i][k]*b.G[k][j]%mod)%mod;
            }
        return c;
    }
    Matrix operator^(const int&k)const{
        Matrix ans,x=*this;
        for(int i=1;i<=N;i++){
            for(int j=1;j<=N;j++)
                ans.G[i][j]=0;
            ans.G[i][i]=1;
        }
        for(int i=k;i;i>>=1,x=x*x)if(i&1)ans=ans*x;
        return ans;
    }
}f,res;
signed main(){
    n=read();K=read();
    Fac[0]=Pw[0]=1;
    for(int i=1;i<=K;i++)Fac[i]=Fac[i-1]*i%mod;
    for(int i=1;i<=K;i++)Pw[i]=Pw[i-1]*2%mod;
    for(int i=1;i<=K+1;i++)f.G[i][i+K+1]=1;
    for(int i=K+2;i<=(K<<1)+2;i++){
        for(int j=1;j<=min(K+1,i-K-1);j++)f.G[i][j]=Pw[(i-K-2)-j+1]*C(i-K-2,j-1)%mod;
        for(int j=K+2;j<=min((K<<1)+2,i);j++)f.G[i][j]=C(i-K-2,j-K-2);
    }
    for(int i=1;i<=K+1;i++)f.G[(K<<1)+3][i]=Pw[K-i+1]*C(K,i-1);
    for(int i=K+2;i<=(K<<1)+2;i++)f.G[(K<<1)+3][i]=C(K,i-K-2);
    f.G[(K<<1)+3][(K<<1)+3]=1;
    res.G[1][1]=1;
    for(int i=K+2;i<=(K<<1)+2;i++)res.G[i][1]=1;
    res.G[(K<<1)+3][1]=1;
    f=f^(n-1);
    res=f*res;
    printf("%lld\n",res.G[(K<<1)+3][1]);
    return 0;
}

posted @ 2021-11-05 12:38  pidan007  阅读(28)  评论(0编辑  收藏  举报