首页 > 编程语言 >【学习笔记】Bostan-Mori 算法

【学习笔记】Bostan-Mori 算法

时间:2023-07-02 19:22:40浏览次数:48  
标签:Bostan dfrac Poly 算法 Mori 奇次 mod

其实是用于常系数齐次线性递推,只不过本篇博文只讲解如何求分式的高次项系数。

已知多项式 \(f(x),g(x)\),要求:\([x^k]\dfrac{f(x)}{g(x)}\),其中 \(f(x),g(x)\) 的次数为 \(n,m\),\(n,m\le 10^5,k\le 10^9\)。

算法流程如下:

分式上下同乘 \(g(-x)\),也就是 \(g\) 的奇次项都取反的多项式,得到:

\[[x^k]\dfrac{f(x)}{g(x)}=[x^k]\dfrac{f(x)g(-x)}{g(x)g(-x)} \]

分母部分一个重要的性质是,由于奇次项系数为相反数,那么最终卷积的结果奇次项都为 \(0\),所以 \(g(x)g(-x)=H(x^2)\),把 \(f(x)g(-x)\) 奇偶分类,变成 \(f(x)g(-x)=F(x^2)+xG(x^2)\),这样可以得到:

\[[x^k]\dfrac{f(x)}{g(x)}=[x^k]\dfrac{f(x)g(-x)}{g(x)g(-x)}=[x^k]\dfrac{F(x^2)+xG(x^2)}{H(x^2)} \]

注意到 \([x^k]\) 只会由分子中某个多项式贡献而来,之后上下的自变量就可以由 \(x^2\) 变为 \(x\),具体地:

\[[x^k]\dfrac{f(x)}{g(x)}=[x^k]\dfrac{f(x)g(-x)}{g(x)g(-x)}=[x^k]\dfrac{F(x^2)+xG(x^2)}{H(x^2)}= \begin{cases} [x^{\lfloor k/2\rfloor}]\dfrac{F(x)}{H(x)}&k\mid 2\\ [x^{\lfloor k/2\rfloor}]\dfrac{G(x)}{H(x)}&k\not\mid 2 \end{cases}\]

每次减半,最终 \(k=0\) 时输出常数项的结果即可。注意到每次卷积规模扩大后只取一半系数使规模减小,所以复杂度 \(O(n\log n\log k)\)。

inline void Bostan_Mori(int N,Poly F,Poly G){
    int L=F.deg;
    Poly H,A,B;
    F.set(L<<1),G.set(L<<1),H.set(L<<1),A.set(L<<1),B.set(L<<1);
    while(N){
        H=G;
        for(int i=1;i<L;i+=2) H[i]=mod-H[i];
        F.NTT(L<<1,1),G.NTT(L<<1,1),H.NTT(L<<1,1);
        for(int i=0;i<L<<1;++i) A[i]=F[i]*H[i]%mod,B[i]=G[i]*H[i]%mod;
        A.NTT(L<<1,0),B.NTT(L<<1,0);
        for(int i=0;i<L;++i) B[i]=B[i*2];
        for(int i=0;i<L;++i) A[i]=A[2*i+(N&1)];
        A.clear(L,(L<<1)-1),B.clear(L,(L<<1)-1);
        F=A,G=B;
        N>>=1;
    }
    printf("%llu\n",F[0]*q_pow((int)G[0],mod-2,mod)%mod);
}

标签:Bostan,dfrac,Poly,算法,Mori,奇次,mod
From: https://www.cnblogs.com/SoyTony/p/Learning_Notes_about_Bostan-Mori_Algorithm.html

相关文章

  • 算法——二分查找
    1、在有序数组中查找元素的第一个和最后一个位置1classSolution{2publicint[]searchRange(int[]nums,inttarget){3intleftindex=binarySearch(nums,target);4intrightindex=binarySearch(nums,target+1)-1;5if(leftindex=......
  • 算法学习
    今天听杨老师说的,我们要去学和发展不同那些在it培训班的领域,但是我们只能从那些B站那些培训课去学习,并没有亮点,可能毕业后,还不如培训班出来的呢,所以我打算算法上面下下功夫,以后的计划是加强javaC++这两门语言基础,然后每天一道算法题。 ......
  • 二分算法学习笔记与总结
    二分算法学习笔记与总结目录二分二分原理整数二分二分查找原理二分查找模板模板一模板二二分查找用法题目1(模板)(二分查找)题目大意题目分析CODE题目2(运用)(二分查找)题目大意题目分析CODESTL中的二分查找lower_bound()upper_bound()浮点二分浮点数二分模板浮点数二分答案模板题目......
  • Snap算法学习01-03Snap中的类及其定义
        //graph.h定义的基本类型无向图  ///Undirectedgraph.##TUNGraph::ClassclassTUNGraph 有向图///Directedgraph.##TNGraph::ClassclassTNGraph 二部图///Bipartitegraph.##Bipartite_graphclassTBPGraph 多重图///Directedmultigr......
  • 什么是算法?
    扎实打牢数据结构算法根基,从此不怕算法面试系列之001week0102-01什么是算法? 1、什么是算法?为了明确什么是算法,我们会从简单的查找功能开始讲起。查找其实一个一个非常简单的算法,但我们会为这个查找功能的算法做如下工作:让查找的功能适应更多的数据类型通过查找的例......
  • 数据结构和算法-2023.07.01
    数据结构杂记回忆以前的一些零散的知识点杂谈......
  • 二叉树中的递归算法(二)
    从二叉树遍历看递归二叉树二叉树(binarytree)是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树。二叉树的遍......
  • 2023-07-01:redis过期策略都有哪些?LRU 算法知道吗?
    2023-07-01:redis过期策略都有哪些?LRU算法知道吗?答案2023-07-01:缓存淘汰算法(过期策略)当Redis的内存超出物理内存限制时,内存中的数据就会频繁地与磁盘进行交换,这个过程叫做交换(swap)。由于交换的高开销,Redis的性能会急剧下降。对于访问频率较高的Redis实例来说,这样低效的存取效率......
  • 2023-07-01:redis过期策略都有哪些?LRU 算法知道吗?
    2023-07-01:redis过期策略都有哪些?LRU算法知道吗?答案2023-07-01:缓存淘汰算法(过期策略)当Redis的内存超出物理内存限制时,内存中的数据就会频繁地与磁盘进行交换,这个过程叫做交换(swap)。由于交换的高开销,Redis的性能会急剧下降。对于访问频率较高的Redis实例来说,这样低效的存取效率几乎......
  • 列车算法
    [资料来源](http://www.ssw.uni-linz.ac.at/General/Staff/TW/Wuerthinger05Train.pdf)http://www.ssw.uni-linz.ac.at/General/Staff/TW/Wuerthinger05Train.pdf程序可以在两次垃圾收集运行之间执行任何操作,例如更改指针。为了便于讨论,我们假设一个对象只适合于一个单块。考虑以......