bzoj #4161. Shlw loves matrixI 常系数线性递推

常系数线性递推

题目链接

做法:容易得到一个\(k^3logn\)的做法,考虑更快。

需要利用矩阵特征方程f(x) (恰好前些天刚学

\(A^n\)\(f(A)\)可以对其取模。之后就可以快速求出了。

我学的不深很难进行证明 但是可以理解。需要多项式取余 暴力的话复杂度\(k^2logn\)

code
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 2000000000
#define inf 100000000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define pii pair<int,int>
#define mk make_pair
#define P 1000000007ll
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define sq sqrt
#define l(x) s[x].l
#define r(x) s[x].r
#define S second
#define mod 1000000007
#define sc(A) scanf("%d",&A)
#define scs(A) scanf("%s",A);
#define put(A) printf("%d\n",A)
#define min(x,y) (x>=y?y:x)
#define max(x,y) (x>=y?x:y)
#define add(x,y) (x+y>=mod?x+y-mod:x+y)
using namespace std;
const int MAXN=2010;
int n,k;
int a[MAXN],b[MAXN];
int f[MAXN<<1],g[MAXN<<1],tmp[MAXN<<1];
inline void gx(int &x)
{
	x=(x%mod+mod)%mod;
	return;
}
inline void mul(int *f,int *g)
{
	rep(0,k-1,i)rep(0,k-1,j)
	{
		tmp[i+j]+=(ll)f[i]*g[j]%mod;
		gx(tmp[i+j]);
	}
	for(int i=2*k-2;i>=k;--i)
	{
		int ww=tmp[i];
		for(int j=k;j>=0;--j)
		{
			tmp[i-k+j]-=(ll)ww*a[j]%mod;
			gx(tmp[i-k+j]);
		}
	}
	rep(0,k-1,i)f[i]=tmp[i],tmp[i]=0;
}
inline void solve(int p)
{
	while(p)
	{
		if(p&1)mul(f,g);
		mul(g,g);p=p>>1;
	}
}
int main()
{
	freopen("1.in","r",stdin);
	sc(n);sc(k);
	rep(0,k-1,i)
	{
		sc(a[i]);
		a[i]=-a[i];
	}
	reverse(a,a+k);
	gx(a[0]);
	rep(1,k,i)
	{
		sc(b[i]);
		gx(a[i]);gx(b[i]);
	}
	a[k]=1;
	if(n<k){put(b[n+1]);return 0;}
	f[0]=1;g[1]=1;
	solve(n);
	int ans=0;
	rep(0,k-1,i)
	{
		ans+=(ll)f[i]*b[i+1]%mod;
		gx(ans);
	}
	put(ans);
	return 0;
}
posted @ 2022-11-17 16:24  chdy  阅读(20)  评论(0编辑  收藏  举报