[BZOJ4161]Shlw loves matrixI
Posted ZLTJohn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ4161]Shlw loves matrixI相关的知识,希望对你有一定的参考价值。
题目描述
给定数列 hn前k项,其后每一项满足
hn = a1*h(n-1) + a2*h(n-2) + … + ak*h(n-k)
其中 a1,a2…ak 为给定数列。请计算 h(n),并将结果对 1000000007 取模输出。
第 1 行包含两个整数 n,k
第 2 行包含 k 个整数 a1,a2…ak
第 3 行包含 k 个整数h[0],h[1],…,h[k-1]
n <= 10^9;k <= 2000; abs(hi)<=10^9; abs(ai)<=10^9
常系数齐次线性递推[链接]
补充一下多项式取模,你要算
xn mod f(x)
x
n
m
o
d
f
(
x
)
,那么我们可以像快速幂一样,从小到大做出
x2i mod f(x)
x
2
i
m
o
d
f
(
x
)
的值,然后乘在一起就行了。卷积可以暴力卷积。
你当然可以FFT优化了(逃
代码
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
//开 O2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
using namespace std;
#define fo(i,j,k) for(i=j;i<=k;i++)
#define fd(i,j,k) for(i=j;i>=k;i--)
#define cmax(a,b) (a=(a>b)?a:b)
#define cmin(a,b) (a=(a<b)?a:b)
typedef long long ll;
typedef double db;
const int N=4005+5,mo=1e9+7;
int t[N],f[N],a[N],h[N],c[N],X[N],revk,n,k,i,j,ans,xs;
int ksm(int x,int y)
int ret=1;
while (y)
if (y&1) ret=1ll*ret*x%mo;
y>>=1;
x=1ll*x*x%mo;
return ret;
void mult(int *A,int *B,int *C)
fo(i,0,2*k) t[i]=0;
fo(i,0,k)
fo(j,0,k)
t[i+j]=(t[i+j]+1ll*A[i]*B[j])%mo;
fd(i,2*k,k)
if (t[i])
//t[i]=xs*C[k]
xs=1ll*t[i]*revk%mo;
fo(j,0,k)
t[i-j]=(t[i-j]-1ll*xs*C[k-j])%mo;
fo(i,0,2*k) A[i]=t[i];
void polymod(int n)
a[0]=-1;
fo(i,0,k) f[k-i]=-a[i];
revk=ksm(f[k],mo-2);
//x^n mod sumf[i]x^i
c[0]=1;
X[1]=1;
while (n)
if (n&1) mult(c,X,f);
n>>=1;
mult(X,X,f);
int main()
freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
scanf("%d %d",&n,&k);
fo(i,1,k)
scanf("%d",a+i);
fo(i,0,k-1)
scanf("%d",h+i);
fo(i,k,k*2)
fo(j,1,k)
h[i]=(h[i]+1ll*a[j]*h[i-j])%mo;
if (n<=k*2)
if (h[n]<0) h[n]+=mo;
printf("%d\\n",h[n]);
return 0;
polymod(n-k);
fo(i,0,k-1)
ans=(ans+1ll*h[i+k]*c[i])%mo;
if (ans<0) ans+=mo;
printf("%d\\n",ans);
以上是关于[BZOJ4161]Shlw loves matrixI的主要内容,如果未能解决你的问题,请参考以下文章