叉姐论文:http://www.docin.com/p-724323397.html
a[i]=sigma(a[j]*b[k-j]) 求第n项
标准的常系数线性递推,用矩阵乘法可以做到o(k^3*logn)
但是如果用特征多项式优化的话,可以把矩阵乘法换成多项式乘法,从而做到o(k^2logn)
首先根据hamilton-cayley定理,一个矩阵的特征多项式是这个矩阵的化零多项式,因此假设最高次为第k次方项,我们可以将特征多项式的第k次方项用0~k-1次方项线性表出,同理k+1次方项可以用1~k次方项线性表出,再把第k次方项拆开,则k+1次方项也可以由0~k-1次方项线性表出,如此归纳下去,矩阵的任意次方项都可以由0~k-1次方项线性表出,那么使用快速幂的话,可以在o(k^2logn)的时间算出每一项的系数,也就是说任意次方的矩阵都可以等价于k个矩阵分别作用于向量再加起来,然后注意到这k个矩阵涉及到的最高项是a[k-1+k-1]项,也就是说可以用o(k^2)的时间算出前2k-2项的话,这k个向量也都被确定了,则要求的向量也可以计算出来。
至于如何求得特征多项式,对于这种线性递推式,按系数所在的行拉普拉斯展开,每一个余子式都可以轻易地化为对角阵的行列式(其实对角上的值都不要动就可以化为对角阵),最后可以注意到-1会被乘两次。
关于推广到一般得矩阵乘法的问题,最大的瓶颈在于最后那k个矩阵分别乘向量,容易看出,一般的递推式会涉及到前k^2项,因此光是求初项就是o(k^3)的,而一般的相似于对角阵的做法,求基变换矩阵需要高斯消元也是o(k^3)。
如果用fft做多项式乘法的话,貌似可以继续优化,但是求初项怎么办,我还不清楚。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
const int mo=10000;
using namespace std;
struct Coe{
int p[205];
Coe operator *(const Coe &b) const;
};
int ans[205],h[205],N,k,K[205];
int a[205],b[205];
Coe Coe::ope