[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的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ]4162: shlw loves matrix II

bzoj4161 (k^2logn求线性递推式)

BZOJ3309: DZY Loves Math

BZOJ3563 DZY Loves Chinese

[BZOJ3309]DZY Loves Math

bzoj3309DZY Loves Math