热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

形式幂级数[学习笔记]

形式幂级数沉迷多项式,无法自拔不具体写了看笔记本,这里稍微记一下。目录多项式的各种运算伯努利数拉格朗日反演任意模数卷积我的三模数ntt跑得好慢,然后拆系数fft跑的好快设\(M\lceil

形式幂级数

沉迷多项式,无法自拔...

不具体写了看笔记本,这里稍微记一下。

目录

  1. 多项式的各种运算
  2. 伯努利数
  3. 拉格朗日反演


任意模数卷积

我的三模数ntt跑得好慢,然后拆系数fft跑的好快

\(M = \lceil P \rceil\),将整数表示成\(k\cdot M+b\)的形式

\(x\)\(y\)进行卷积,分别表示称\(a\cdot M + b,\ c\cdot M + d\)
\[(a\cdot M + b)\cdot (c\cdot M + d) = ac M^2 + (ad+bc)M + bd\]
\(a,b,c,d\)进行dft和idft即可

每个数大小在\(10^{14}\)级别,可以使用复数下fft,共进行7次运算

通常M取\(32768=2^{15}\)

根据猜测,系数表示不溢出double点值表示就不会溢出double。这玩意应该只能承受一次点值乘法

    void mul_any(int *x, int *y, int lim) {
for(int i=0; i a[i].x = x[i] >> 15; b[i].x = x[i] & 32767;
c[i].x = y[i] >> 15; d[i].x = y[i] & 32767;
}
dft(a, 1); dft(b, 1); dft(c, 1); dft(d, 1);
for(int i=0; i cd _a = a[i], _b = b[i], _c = c[i], _d = d[i];
a[i] = _a * _c;
b[i] = _a * _d + _b * _c;
c[i] = _b * _d;
}
dft(a, -1); dft(b, -1); dft(c, -1);
for(int i=0; i ll _a = (ll) floor(a[i].x + 0.5) %mo, _b = (ll) floor(b[i].x + 0.5) %mo, _c = (ll) floor(c[i].x + 0.5) %mo;
printf("%lld ", ((_a <<30) %mo + (_b <<15) %mo + _c) %mo);
}
}



以下复杂度均为\(T(n) = T(n/2) + O(nlogn) =O(nlogn)\)

模板在最下方


多项式求逆元


\[A(x) * B(x) \equiv 1 \pmod {x^n}\]

  • 注意到这时候\(A(x)*B(x)\)\(1...n-1\)次项系数为0

用倍增的思想,已知\(\mod x^{\lceil \frac{l}{2} \rceil}\)的逆元\(B_0(x)\)\(\mod x^l\)下的逆元\(B(x)\)

\(l=1\)时,\(b_0 = a_0^{-1}\),可以发现多项式有逆的充要条件是常数项有逆

两式相减,然后平方,同乘\(A(x)\),得到
\[B(x) \equiv B_0(x) * (2 - A(x) * B_0(x)) \pmod {x^l}\]

处理\(\mod x^l\)时,\(l\)就是当前的次数界,次数\(\ge l\)的都整除没了。

可以理解为只关心前l项



多项式开根


\[B^2(x) \equiv A(x) \pmod {x^n}\]
同样倍增的思想

已知\(\mod x^{\lceil \frac{l}{2} \rceil}\)的平方根\(B_0(x)\)\(\mod x^l\)下的平方根\(B(x)\)

\(l=1\)时,\(b_0 \equiv \sqrt{a_0} \pmod x\),可能需要二次剩余

移项化简后得到
\[B(x) \equiv 2^{-1}\cdot (B_0(x) + A(x) * B_0^{-1}(x)) \pmod{x^n}\]
同时还需要求逆...



牛顿迭代法

给出\(G(x)\),求\(F(x)\)
\[G(F(x)) \equiv 0 \pmod{x^n}\]
倍增的思想。将\(G(F(X))\)\(F_0(x)\)处泰勒展开得到
\[F(x) \equiv F_0(x) - \frac{G(F_0(x))}{G'(F_0(x))} \pmod{x^l}\]
也可以用这个式子求逆元和开根,最后的结果式子一样。


  • 多项式求ln和exp就是和对应的麦克劳林级数复合,所以要求常数项为0



多项式求ln

给出\(F(x) = 1 + \sum_{i \ge 1}f_ix^i\)

求一下导
\[\ln F(x) = \int \frac{F'(x)}{F(x)}dx\]



多项式求exp

给出\(A(x) = \sum_{i \ge 1}a_ix^i\)
\[e^{A(x)} - B(x) \equiv 0 \pmod {x^n}\]
取对数后使用牛顿迭代法
\[B(x) = B_0(x)(1 - \ln B_0(x) + A(x))\]


多项式k次幂

\(A(x)\)的常数项为1
\[A(x)^k = exp(k \ln A(x))\]

否则提取最低次项\(ax^d\)
\[A(x)^k = (ax^d)^k (\frac{A(x)}{ax^d})^k\]



伯努利数

wiki

用来解决等幂求和问题
\[\begin{align}\sum_{i=0}^{n-1} i^m = \frac{1}{m+1}\sum_{i=0}^m \binom{m+1}{i}B_i^- n^{m+1-i} \\S_m(n) = \sum_{i=1}^{n} i^m = \frac{1}{m+1}\sum_{i=0}^m \binom{m+1}{i}B_i^+ n^{m+1-i} \\\end{align}\]
复杂度与幂次有关

除了\(B_1\),其他奇数项都是0。\(B_1^+ = \frac{1}{2},B_1^-=-\frac{1}{2}\)

\(0^0=1\)

递推关系

\(n=1, m\neq 0\),
\[\sum_{i=0}^m \binom{m+1}{i}B_i^- = 0,\ B_0=1, B_1^-=-\frac{1}{2}\]

指数型生成函数

对于\(B^-\),
\[\sum_{i=0}^\infty B_i\frac{x^i}{i!} =\frac{x}{e^x - 1} = (\sum_{i=0}^\infty \frac{x^i}{(i+1)!})^{-1}\]

使用多项式求逆元即可预处理伯努利数. 求\(\mod x^{n+1}\)意义下逆元


预处理任意模数伯努利数的模板



拉格朗日反演

复合逆(反函数):

没有常数项的\(f(x), g(x)\)\(f(g(x))=x\),那么互为复合逆,\(f_1g_1=1,g(f(x))=x\)

用拉格朗日反演可以\(O(nlogn)\)复合逆某一项的系数
\[[x^n]g(x) = \frac{1}{n}[\omega^{n-1}](\frac{\omega}{f(\omega)})^n\]
可以配合多项式k次幂使用。

生成函数中出现x之后可以用啦。



模板
namespace ntt {
int g = 3, rev[N];
void dft(int *a, int n, int flag) {
int k = 0; while((1< for(int i=0; i rev[i] = (rev[i>>1]>>1) | ((i&1)<<(k-1));
if(i }
for(int l=2; l<=n; l<<=1) {
int m = l>>1, wn = Pow(g, flag == 1 ? (P-1)/l : P-1-(P-1)/l);
for(int *p = a; p != a+n; p += l)
for(int k=0, w=1; k int t = (ll) w * p[k+m] %P, r = p[k];
p[k+m] = (r - t + P) %P;
p[k] = (r + t) %P;
}
}
if(flag == -1) {
ll inv = Pow(n, P-2);
for(int i=0; i }
}

void inverse(int *a, int *b, int l) {
static int t[N];
if(l == 1) {b[0] = Pow(a[0], P-2); return;}
inverse(a, b, l>>1);
int n = l<<1;
for(int i=0; i0;
dft(t, n, 1); dft(b, n, 1);
for(int i=0; i2 - (ll) t[i] * b[i] %P + P) %P;
dft(b, n, -1); for(int i=l; i0;
}

void sqrt(int *a, int *b, int l) {
static int t[N], ib[N];
if(l == 1) {b[0] = 1; return;}
sqrt(a, b, l>>1);
int n = l<<1;
for(int i=0; i0, ib[i] = ib[i+l] = 0;
inverse(b, ib, l);
dft(t, n, 1); dft(b, n, 1); dft(ib, n, 1);
for(int i=0; i dft(b, n, -1); for(int i=l; i0;
}

void ln(int *a, int *b, int l) {
static int da[N], ia[N];
int n = l<<1;
for(int i=0; i0;
for(int i=0; i-1; i++) da[i] = (ll) (i+1) * a[i+1] %P;
inverse(a, ia, l);
dft(da, n, 1); dft(ia, n, 1);
for(int i=0; i dft(b, n, -1);
for(int i=l-1; i>0; i--) b[i] = (ll) inv[i] * b[i-1] %P; b[0] = 0;
for(int i=l; i0;
}

void exp(int *a, int *b, int l) {
static int t[N];
if(l == 1) {b[0] = 1; return;}
exp(a, b, l>>1);
int n = l<<1;
for(int i=0; i0;
ln(b, t, l);
for(int i=0; i0] = (t[0] + 1) %P;
dft(b, n, 1); dft(t, n, 1);
for(int i=0; i dft(b, n, -1); for(int i=l; i0;
}

void power(int *a, int k, int l) {
static int t[N];
int n = l<<1;
for(int i=0; i0;
ln(a, t, l);
for(int i=0; i for(int i=0; i0;
exp(t, a, l);
}
}

推荐阅读
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • HDFS2.x新特性
    一、集群间数据拷贝scp实现两个远程主机之间的文件复制scp-rhello.txtroothadoop103:useratguiguhello.txt推pushscp-rr ... [详细]
  • 从零学Java(10)之方法详解,喷打野你真的没我6!
    本文介绍了从零学Java系列中的第10篇文章,详解了Java中的方法。同时讨论了打野过程中喷打野的影响,以及金色打野刀对经济的增加和线上队友经济的影响。指出喷打野会导致线上经济的消减和影响队伍的团结。 ... [详细]
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 摘要: 在测试数据中,生成中文姓名是一个常见的需求。本文介绍了使用C#编写的随机生成中文姓名的方法,并分享了相关代码。作者欢迎读者提出意见和建议。 ... [详细]
author-avatar
李-小-霞_973
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有