.article-info-tag,button{text-transform:uppercase}.day,.postMeta,.postSticky{position:relative}.postTitle a:link,html{-webkit-tap-highlight-color:transparent}#blog-calendar,.code-copay-btn,.code-hljs-len,.hidden{visibility:hidden}#EntryTag,#blogTitle h1{margin-top:20px}#EntryTag a,.postSticky{background:#6fa3ef}#blogTitle h1 a:hover,.dayTitle a,a,a:active,a:link,a:visited{color:#5c8ec6}#calendar table a:hover,#navList a:hover,.postDesc a:hover,a:active,a:hover,a:link,a:visited,button{text-decora…ryTag a:visited{color:#666}#BlogPostCategory a,#EntryTag a{height:20px;line-height:20px;color:#fff!important;padding:3px 5px;border-radius:3px;margin:2px 5px 0;text-decoration:none;font-size:14px}#BlogPostCategory a:hover,#EntryTag a:hover{transition:all .3s linear 0s;opacity:.8}#topics .postDesc{padding-left:0;width:100%;text-align:left;color:#666;margin-top:5px;background:0 0}.feedbackListSubtitle-louzhu:after,.feedbackListSubtitle:after,.feedbackListSubtitle:before{top:11px;right:100%;left:-1

Luogu P4732 常系数齐次线性递推

\(\mathtt{Description}\)

求一个满足 \(k\) 阶齐次线性递推数列 \({a_i}\) 的第 \(n\) 项,即:

\[a_n=\sum\limits_{i=1}^{k}f_i \times a_{n-i} \]

\(\mathtt{restrictions:}n=10^9,k = 32000\)

\(\mathtt{Solution}\)

\(\mathtt{Pre-Knowledge}\)

多项式取模。

关于求线性递推数列的解法BJpers2大佬的题解已经说的很清楚了,这里主要写一下在打代码的时候需要注意的地方。

我们其实就是要求多项式 \(x^n\)\(p(x)= x^k-f_1x^{k-1}-\cdots -f_kx^0\) 的模意义下的结果。

所以可以考虑快速幂,每次多项式取模就可以了,然后要注意以下两个点:

  1. 对于多项式封装使用 std::vector 的同学,需要注意模的多项式的 size 大于原多项式的情况。

  2. 原式有小于 \(0\) 的情况,需要判断掉。

把代码放一下吧:

\(\mathtt{Code}\)

inline std::pair<vector<int>,vector<int> > Div(vector <int> f,vector <int> g) {
    int n = f.size(),m = g.size();
    if (n - m < 0) return std::make_pair(vector <int> (1,0),f) ;
    vector <int> fr(n),gr(m),igr,q(n - m + 1),r(m);
    for (int i = 0; i < n; ++i) fr[n - i - 1] = f[i] ;
    for (int i = 0; i < m; ++i) gr[m - i - 1] = g[i] ;
    gr.resize(n - m + 1) ;
    igr = Inv(gr),fr = fr * igr ;
    for (int i = 0; i < n - m + 1; ++i) q[i] = fr[n - m - i] ;
    g = q * g ;
    for (int i = 0; i < m; ++i) r[i] = (f[i] - g[i] + mod) % mod ;
    return std::make_pair(q,r) ;  
  }

  inline int LR(vector<int> a,vector<int> p,int n) {
    int k = a.size() ;
    vector<int> f(2),res(1) ;
    f[1] = res[0] = 1; 
    while (n) {
      if (n & 1) {
        res = res * f; 
        auto tmp = Div(res,p) ;
        res = tmp.second ;
      }
      f = f * f ;
      auto temp = Div(f,p) ;
      f = temp.second,n >>= 1;
    }
    int ans = 0 ;
    for (int i = 0; i < k; ++i) ans = (ans + 1ll * a[i] * res[i] % mod) % mod ;
    return ans ;
  }
posted @ 2021-07-21 11:02  feicheng  阅读(30)  评论(0编辑  收藏  举报