Processing math: 100%
论如何在没有压感屏幕的手机上实现压力感应

关于常系数线性递推...

YYY posted @ 2016年4月25日 21:45 in 科技?科技! with tags 多项式求逆 多项式乘法 线性递推 , 921 阅读
_THIS_IS_START_OF_ARTICLE_
----------------------------------------------------------------------------------
最近研究了一下这个问题...
最后实现的时候花了整整两天(当然其中大部分时间都在浪...)
主要还是不会的太多了..=_=感觉学到了好多新知识...
然后在学习关于多项式求逆的那一套理论的时候,发现Picks博客上就有这个问题的解法而且貌似比我的简单得多..=_=
不过我和他的方法貌似不一样(窝并看不懂他在说什么...)
所以也算是自己的一个发现吧
另外期间大部分我不能解决的问题都是问的Skydec...
----------------------------------------------------------------------------------
首先是问题:
已知f(n)的递推式f(n)=k1i=0aif(nk+i)(给定k和向量a)
并且给出f(0)~f(k1)
现在给定一个n,求f(n)
----------------------------------------------------------------------------------
O(lg(n)k3))做法:
可以使用矩阵乘法
首先可以构造出初始向量a=(f(0),f(1)...f(k1))T
再构造出转移矩阵A:
(010000100001a0a1a2ak1)
然后Ana的第1行第1列就是答案
然后就可以快速幂辣
----------------------------------------------------------------------------------
O(lg(n)k2))做法:
首先得到了f(n)=k1i=0aif(n20k+i) ...式1
把式1代入式1:
f(n)=k1i=0aik1j=0ajf(n21k+i+j) 
可以暴力求,最后得到的式子共有2k项,即:
f(n)=2k1i=0aif(n21k+i)...式1.5 
然后把式1代入式1.5f(n21k+k)~f(n21k+2k1)这几项中,就得到了
f(n)=k1i=0bif(n21k+i) ...式2
这样不断地把自己代入自己,然后把式1代入自己的后k项,就可以的到式p:(我把f(n2p+1k+i)叫做第i项)
f(n)=k1i=0bif(n2pk+i) ...式p
这样就是一个倍增的过程,每次可以把k的系数乘以2
然后n是奇数的时候,需要往后推一项,把式1带进去即可
----------------------------------------------------------------------------------
O(lg(n)lg(k)k))做法:
重头戏来辣=w=
考虑上面那个方法的优化
主要分为两步:自己代入自己和把后k项展开到前k
首先看自己代入自己这个过程:
f(n)=k1i=0aik1j=0ajf(n2p+1k+i+j) 
聪明的读者已经发现,这就是个卷积,所以做一个多项式乘法就好了...
 
现在假设已经求到了f(n)=k1i=0cif(n21k+i)
另外为了方便表示,不放把a翻转一下然后移动一下位置(设这样得到的向量是a):
f(n)=ki=1aif(ni)
然后来考虑第二步,这一步中,显然k~2k1这些项会对0~k1这些项产生贡献
聪明的读者不难发现,第s项(ks<2k)对第t项(0t<k)产生的贡献是:
g(s,t)=cski=1b1,b2...biij=1bi=stbj1biktki=1abi
而第t项最后得到的贡献就是dt=ks<2kg(s,t)
听起来很麻烦?
先假设不考虑bi
不放把t加上bi
因此有:
ct=cski=1b1,b2...biij=1bi=stbj1ki=1abi
其中kt<2k
这就简单多了
假设Aa的生成函数
A[k]表示Ak次项系数
那么不难发现上式就等于
ct=cs(ki=0Ai)[st]
=cs((+i=0Ai) mod xk)[st]
=cs(1/(1A)) mod xk)[st]
这个显然是一个卷积,于是一个多项式求逆一个多项式乘法就可以求到了
现在求到了c,考虑将他的各项减去bi(bikt)来得到最后d
因此:
dt=ks<2kcsast
然后这也显然是个卷积,多项式乘法即可
至此问题就解决了,最后ci=ci+di(0i<k)就是展开完之后的f(n)的表达式的前k
只用到了多项式乘法和多项式求逆,这两个都是O(lg(k)k)
然后算上倍增的时间,最后的时间复杂度O(lg(n)lg(k)k))
 
最后,实现的时候,多项式求逆中会爆精度,所以只能用NTT做(或者用分块乘法...)...
----------------------------------------------------------------------------------
这里有一个很挫的实现:(只实现了最后一步,也就是把f(n)含有2k项的表达式展开成只含有k项的表达式,这是最难也是最关键的一步)
(输入输出格式是:第一行输入k,然后输入a,然后输入有2n项的c,输出展开之后只有n项的c)
----------------------------------------------------------------------------------

 

_THIS_IS_END_OF_ARTICLE_
Avatar_small
zrq 说:
2016年4月26日 21:40

大爷好强%%%


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter