特征多项式优化线性递推

#include <cstdio>
#define EXint __uint128_t

  EXint n,k,p,tmp[3001],ans;

  inline EXint READ(){
    char ch=getchar();EXint ret=0;
    while (ch<‘0‘||ch>‘9‘) ch=getchar();
    while (ch>=‘0‘&&ch<=‘9‘){ret*=10;ret+=ch-‘0‘;ch=getchar();}
    return(ret);
  }

  inline void WRITE(EXint a){
    int cnt=0,typ[101];
    while (a) typ[++cnt]=a%10,a/=10;
    for (int i=cnt;i>=1;i--) putchar(typ[i]+‘0‘);
  }

  struct poly{
    EXint a[3001];

    void mul(poly&b){
      for (int i=0;i<=2*k-2;i++) tmp[i]=0;
      for (int i=0;i<=k-1;i++)
        for (int j=0;j<=k-1;j++)
          tmp[i+j]+=a[i]*b.a[j];

    //对特征多项式取模
      for (int i=2*k-2;i>=k;i--){
        tmp[i-k]+=tmp[i];tmp[i-k+1]+=tmp[i];
      }
      for (int i=k-1;i>=0;i--) a[i]=tmp[i];
    }
  }bas,res;

  int main(){
    n=READ();k=READ();p=READ();
    bas.a[1]=1;res.a[0]=1;
    while (n){
      if (n&(EXint)1) res.mul(bas);
      bas.mul(bas);
      n=n>>1;
    }

    for (int i=0;i<k;i++) ans=ans+res.a[i];//若0-k-1的初始值不为1则乘权值
    if (p!=128) ans&=((((EXint)1)<<p)-1);
    WRITE(ans);
  }
时间: 2025-01-20 01:00:41

特征多项式优化线性递推的相关文章

多校第九场:贪心+矩阵快速幂中间优化+线性递推&amp;线段树递推

HDU 4968 Improving the GPA 思路:贪心的搞吧!比赛的时候想了好久,然后才发现了点规律,然后乱搞1A. 因为贪心嘛!大的情况就是刚开始每个人的分数都是最大的最小值,即绩点4.0的最低分数85,然后最后一个数设为剩余的分数,然后如果小于60就从第一个分数补到这个分数来,然后最后一个分数还小于60,那就用第二个补--依次往下搞,那时我也不知道这样就搞出答案了,我还没证明这个对不对呢,哈哈. 小的情况:小的情况就是先假设每个人都是绩点最小的最大分数,即绩点2.0的最大分数69,

HDU 5863 cjj&#39;s string game ( 16年多校10 G 题、矩阵快速幂优化线性递推DP )

题目链接 题意 : 有种不同的字符,每种字符有无限个,要求用这k种字符构造两个长度为n的字符串a和b,使得a串和b串的最长公共部分长度恰为m,问方案数 分析 : 直觉是DP 不过当时看到 n 很大.但是 m 很小的时候 发现此题DP并不合适.于是想可能是某种组合数学的问题可以直接公式算 看到题解的我.恍然大悟.对于这种数据.可以考虑一下矩阵快速幂优化的DP 首先要想到线性递推的 DP 式子 最直观的想法就是 dp[i][j] = 到第 i 个位置为止.前面最长匹配长度为 j 的方案数 但是如果仔

矩阵乘法优化线性递推

矩阵乘法是线性代数中一块很重要的内容.矩阵乘法的定义很奇怪[1],但正是这种奇怪的性质,让矩阵乘法成为在除了线性代数和其衍生学科(还有诸如矩阵力学之类)外最广泛使用的关于矩阵变换的应用.(什么?FFT不属于矩阵变换吧...) 注: [1]: 矩阵乘法有另外的很多定义,如未说明,指的是中间不带符号的矩阵乘法,即一般矩阵乘积.另有 标量乘积(即所有数乘上一个固定的数),阿达马乘积等,没有那么诡异,但是在大多数问题的用途上也不大. 你不会矩阵乘法?没关系,下一篇会写到的 矩阵乘法的本质 矩阵乘法的本质

矩阵快速幂优化线性递推

我们熟知的斐波那契数列递推公式是: \(f(n)=f(n-1)+f(n-2)\) 假设我们需要求斐波那契数列的第n项,当n非常大(如n=1e9)的时候,递推肯定超时.我们不妨设: \(\binom{f_{n}}{f_{n-1}}=\begin{pmatrix}a & b\\ c & d\end{pmatrix}\binom{f_{n-1}}{f_{n-2}}\) 将等式右边乘开,得到: \(\binom{af_{n-1}+bf_{n-2}}{cf_{n-1}+df_{n-2}}\) 要使其

利用Cayley-Hamilton theorem 优化矩阵线性递推

平时有关线性递推的题,很多都可以利用矩阵乘法来解k决. 时间复杂度一般是O(K3logn)因此对矩阵的规模限制比较大. 下面介绍一种利用利用Cayley-Hamilton theorem加速矩阵乘法的方法. Cayley-Hamilton theorem: 记矩阵A的特征多项式为f(x). 则有f(A)=0. 证明可以看 维基百科 https://en.wikipedia.org/wiki/Cayley–Hamilton_theorem#A_direct_algebraic_proof 另外我在

[HDOJ6172] Array Challenge(线性递推,黑科技)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6172 题意:给一堆东西,就是求个线性递推式,求第n项%1e9+7 杜教板真牛逼啊,线性递推式用某特征值相关的论文板,打表前几项丢进去就出结果了. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long ll; 5 #define rep(i,a,n) for (ll i=a;i<n;i++) 6 #def

根据a(n)/a(n-1)的无理数极限逆推二阶线性递推数列公式

首先看这样一道题目: a(n)=6*a(n-1)-a(n-2),a1=1,a2=5,求b(n)=a(n+1)/a(n)的极限  数列通项两边除以a(n-1) 得: a(n)/a(n-1)=6-a(n-1)/a(n-2) 根据单调有界定理可以证明极限存在 单调性可以用数学归纳法证明,不再赘述 设极限为x 则x=6-1/x x^2-6*x+1=0 解一元二次方程得 x=3+2√2 我举这个例子,是因为,这个例子和2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络E题的数列很像,只不过在后面减了个

BZOJ 4204 取球游戏 循环矩阵优化期望递推

题意:链接 方法:循环矩阵优化期望递推. 解析: 这题递推没啥,主要是循环矩阵优化 我们发现,如果直接上矩阵优化的话是n^3log,所以铁定是过不了了的,然后再观察一下这道题我们要求幂的矩阵,发现他是这种形式 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 1 每一行都是上一行向右窜了一位 所以我们可以用一个一维数组代表这个循环矩阵 并且循环矩阵求和,乘积还是循环矩阵 所以我们就可以用循环矩阵来优化掉一个n 复杂度即变为了n^2log 可过. 代码

HDU - 6172:Array Challenge (BM线性递推)

题意:给出,三个函数,h,b,a,然后T次询问,每次给出n,求sqrt(an); 思路:不会推,但是感觉a应该是线性的,这个时候我们就可以用BM线性递推,自己求出前几项,然后放到模板里,就可以求了. 数据范围在1e15,1000组都可以秒过. 那么主要的问题就是得确保是线性的,而且得求出前几项. #include<bits/stdc++.h> using namespace std; #define rep(i,a,n) for (int i=a;i<n;i++) #define per