題解 CF392C Yet Another Number Sequence
阿新 • • 發佈:2021-11-05
題解 CF392C Yet Another Number Sequence
題意描述
令\(A_i=F_i*i^k\),求\(\sum\limits_{i=1}^{n}A_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*} \]交換求和順序:
考慮將\(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} \]得到轉移矩陣:
初始矩陣:
直接轉移即可。
程式碼如下:
#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;
}