学多项式也有好久了,可是我自己还没怎么认认真真推过柿子,导致啥都不会,然后被吊打。

看来再不回顾一下就不行了啊。

多项式乘法

写了一个好看一点的\(\mathrm{NTT}\)板子,仅供参考。

inline int Add(int x, int y) { return (x + y) % Mod; }
inline int Sub(int x, int y) { return (x - y + Mod) % Mod; }
inline int Mul(int x, int y) { return 1ll * x * y % Mod; }
int fastpow(int x, int y)
{int ans = 1;for (; y; y >>= 1, x = 1ll * x * x % Mod)if (y & 1) ans = 1ll * ans * x % Mod;return ans;
}int r[maxn], w[maxn];
void FFT(int *p, int N)
{for (int i = 0; i < N; i++) if (i < r[i]) std::swap(p[i], p[r[i]]);for (int i = 1, s = 2, t = N >> 1; i < N; i <<= 1, s <<= 1, t >>= 1)for (int j = 0; j < N; j += s) for (int k = 0, o = 0; k < i; ++k, o += t){int x = p[j + k], y = 1ll * w[o] * p[i + j + k] % Mod;p[j + k] = (x + y) % Mod, p[i + j + k] = (x - y + Mod) % Mod;}
}template<typename C>
void PolyMul(int *a, int *b, int N, int P, C cal)
{w[0] = 1, w[1] = fastpow(3, (Mod - 1) / N);for (int i = 0; i < N; i++) r[i] = (r[i >> 1] >> 1) | ((i & 1) << P);for (int i = 2; i < N; i++) w[i] = 1ll * w[i - 1] * w[1] % Mod;FFT(a, N), FFT(b, N); for (int i = 0; i < N; i++) b[i] = cal(a[i], b[i]);FFT(b, N); std::reverse(b + 1, b + N); int invn = fastpow(N, Mod - 2);for (int i = 0; i < N; i++) b[i] = 1ll * b[i] * invn % Mod;
}

泰勒展开

如果\(f(x)\)在\(x_0\)处存在\(n\)阶导,那么有:
\[ f(x) = \sum_{i=0}^n \frac {f^{(i)}(x_0)} {i!} (x - x_0) ^ i + \xi \]
其中\(\xi\)是余项,当\(n\)趋近于无穷大时,\(\xi\)趋近于高阶无穷小。

比如说\(e ^ x = 1 + \frac x{1!} + \frac {x^2}{2!} + \cdots\)

牛顿迭代

首先可以知道多项式的任何一个运算都可以表示成对于一个多项式\(B(x)\)以及一个给定的函数\(F(x)\),求\(F(B(x)) \equiv 0 \pmod {x ^ n}\)

设\(B_n(x)\)表示当模数是\(x ^ n\)的合法解。那么当\(n = 1\)是我们很容易可以得到结果,考虑如何用\(B_n(x)\)推到\(B_{2n}(x)\)。

对\(F(B_{2n}(x))\)在\(B_n(x)\)处泰勒展开,我们得到\(F(B_{2n}(x)) = F(B_n(x)) + F'(B_n(x))(B_{2n}(x) - B_n(x))\)。

那么我们化简一下就是:
\[ B_{2n}(x) = B_n(x) - \frac {F(B_n(x))} {F'(B_n(x))} \]
这样我们就可以倍增求解。

多项式运算

接下来均假设我们要做运算的多项式是\(A(x)\)。

多项式求逆

令\(F(B_n(x)) = A(x) * B_n(x) - 1 \equiv 0\)

于是:
\[ \begin{aligned} B_{2n} &= B_n(x) - \frac {A(x) * B_n(x) - 1} {A(x)} \\ &= B_n(x) - B_n(x)(A(x) * B_n(x) - 1) \\ &= 2B_n(x) - A(x) * B_n^2(x) \end{aligned} \]
注意第一步推到第二步是因为\(B_n(x)\)是\(A(x)\)的逆。

void Inv(int *a, int *b, int N)
{static int c[maxn]; if (N == 1) return (void) (*b = fastpow(*a, Mod - 2));Inv(a, b, (N + 1) >> 1); int L = 1, P = -1; while (L < (N << 1)) L <<= 1, ++P;std::copy(a, a + N, c), std::fill(c + N, c + L, 0);PolyMul(c, b, L, P, [] (int a, int b) { return Mul(Sub(2, Mul(a, b)), b); });std::fill(b + N, b + L, 0);
}

多项式开根

ln一下再exp一下

令\(F(B_n(x)) = B_n^2(x) - A(x) \equiv 0\)

于是有:
\[ B_{2n} = B_n(x) - \frac {B_n^2(x) - A(x)} {2B_n(x)} = \frac 12\left(B_n(x) + \frac {A(x)} {B_n(x)} \right) \]
可以看出多项式开根中需要套用多项式求逆。

void Sqrt(int *a, int *b, int N)
{static int c[maxn], d[maxn]; if (N == 1) return (void) (*b = 1);Sqrt(a, b, (N + 1) >> 1); int L = 1, P = -1; while (L < (N << 1)) L <<= 1, ++P;std::copy(a, a + N, c), std::fill(c + N, c + L, 0);std::fill(d, d + L, 0), Inv(b, d, N), PolyMul(c, d, L, P, Mul);for (int i = 0; i < N; i++) b[i] = Mul(Add(b[i], d[i]), 499122177);
}

多项式\(\ln\)

不需要牛顿迭代。
\[ \begin{aligned} \ln(A(x)) &= B(x) \\ \Rightarrow\frac {A'(x)}{A(x)} &= B'(x) \end{aligned} \]
然后\(A(x)\)就求导求逆,乘起来再积分一下就可以了。

void Ln(int *f, int *g, int N)
{static int A[maxn], B[maxn]; Inv(f, B, N), A[N - 1] = 0;for (int i = 1; i < N; i++) A[i - 1] = Mul(f[i], i);int L = 1, P = -1; while (L < (N << 1)) L <<= 1, ++P;PolyMul(A, B, L, P, Mul), g[0] = 0;for (int i = 1; i < N; i++) g[i] = Mul(B[i - 1], fastpow(i, Mod - 2));std::fill(A, A + L, 0), std::fill(B, B + L, 0);
}

多项式\(\exp\)

令\(F(B_n(x)) = \ln(B_n(x)) - A(x) \equiv 0\)

推下式子可得:
\[ \begin{aligned} B_{2n}(x) &= B_n(x) - \frac {\ln(B_n(x)) - A(x)} {\frac 1 {B_n(x)}} \\ &= B_n(x)(1 - \ln(B_n(x)) + A(x)) \end{aligned} \]

void Exp(int *a, int *b, int N)
{static int c[maxn]; if (N == 1) return (void) (*b = 1);Exp(a, b, (N + 1) >> 1), Ln(b, c, N);int L = 1, P = -1; while (L < (N << 1)) L <<= 1, ++P;for (int i = 0; i < N; i++) c[i] = Sub(a[i], c[i]); c[0] = Add(c[0], 1);PolyMul(c, b, L, P, Mul), std::fill(b + N, b + L, 0);
}

多项式除法

给定一个\(n\)次多项式\(A(x)\)和一个\(m\)次多项式\(B(x)\),求解一个\(n - m\)次的多项式\(Q(x)\)以及一个小于\(n - m\)次的多项式\(R(x)\),使得\(A(x) = Q(x)B(x) + R(x)\)

定义运算\(R\)使得\(A^R(x) = x ^ nA(\frac 1x)\),也就是说将\(A(x)\)的系数翻转。

那么可以得到:
\[ \begin{aligned} A(x) &= Q(x)B(x) + R(x) \\ A\left(\frac 1x\right) &= Q\left(\frac 1x\right)B\left(\frac 1x\right) + R\left(\frac 1x\right) \\ x ^ nA\left(\frac 1x\right) &= \left(x ^ m B\left(\frac 1x\right)\right) * \left( x ^ {n - m} Q\left(\frac 1x\right)\right) + x ^ n R\left(\frac 1x\right) \\ A^R(x) &= Q^R(x)B^R(x) + x^{n-m+1}R^R(x) \\ A^R(x) &\equiv Q^R(x)B^R(x) \pmod{x ^ {n - m + 1}} \\ Q^R(x) &\equiv \frac {A^R(x)} {B^R(x)} \pmod{x ^ {n - m + 1}} \end{aligned} \]
那么这样就可以用多项式求逆求出\(Q\),再用\(R(x) = A(x) - Q(x)B(x)\)即可求出\(R\)。

转载于:https://www.cnblogs.com/cj-xxz/p/11166903.html

「学习笔记」多项式相关相关推荐

  1. 「学习笔记」多项式的蛇皮操作

    文章目录 「学习笔记」多项式的蛇皮操作 前置知识 趋近 自然常数 对数 逆元 导函数 牛顿迭代与泰勒公式 不定积分与定积分 多项式乘法 多项式求逆元 多项式除法/取模 多项式牛顿迭代法 多项式开根 「 ...

  2. 「学习笔记」黑马面面布局开发

    「学习笔记」黑马面面布局开发 黑马面面布局开发 一.目的 1.1 技术方案 1.2 代码规范 1.2 目录规范 二.流程开发 2.1 蓝湖/摹客协作平台 2.2 适配方案 2.3 初始化文件 2.4 ...

  3. 「学习笔记」移动Web开发之flex布局9

    「学习笔记」移动Web开发之flex布局9 一.flex布局体验 1.1 传统布局与flex布局 1.2 初体验 二.flex布局原理 2.1 布局原理 三.flex布局父项常见属性 3.1 常见父项 ...

  4. 「学习笔记」移动Web开发之rem适配布局10

    「学习笔记」移动Web开发之rem适配布局10 一.rem单位 1.1 rem 单位 二.媒体查询 2.1 什么是媒体查询 2.2 语法规范 2.2.1 mediatype 查询类型 2.2.2 关键 ...

  5. 「学习笔记」HTML5CSS3提高6(上)

    「学习笔记」HTML5&CSS3提高6(上) HTML5新特性 概述 语义化标签 (★★) 多媒体标签 视频标签- video(★★★) 基本使用 兼容写法 video 常用属性 音频标签- ...

  6. 【学习笔记】多项式相关算法

    [学习笔记]多项式相关算法 手动博客搬家: 本文发表于20181125 13:19:28, 原地址https://blog.csdn.net/suncongbo/article/details/844 ...

  7. 「学习笔记」品优购项目-上(页面公共部分 )

    「学习笔记」品优购项目-上 品优购项目-上 目标 品优购项目规划 网站制作流程 品优购项目介绍 品优购项目的学习目的 开发工具以及技术栈 开发工具 技术栈 品优购项目搭建工作 创建的文件夹如下(称为项 ...

  8. 「学习笔记」ISAP求最大流

    ISAP学习笔记 ISAP是OI中求最大流的常用方法之一.相对于Dinic,ISAP的速度提升了很多,但编码复杂度也上升了不少. 约定 采用邻接表存储图,对于每条弧,增加一条容量为0的逆向边. d数组 ...

  9. 「学习笔记」无标号生成树计数总结

    感觉关于树/图计数是一门博大精深的学问,不知道这辈子有没有搞到足够明白的机会了啊QwQ 一.无标号有根树计数: 基本上是这篇的详细版本. 考虑令fnf_nfn​表示n个点的无标号有根树数量,其生成函数 ...

最新文章

  1. 知识点回顾-简单的TableView单组数据展示/多组数据展示
  2. 最高补助1000万元!这类程序员2020年要过好日子了……
  3. 程序员最害怕的5件事,你中招了吗?
  4. springboot controller 分页查询_Spring Boot实战分页查询附近的人:Redis+GeoHash+Lua
  5. 【报错笔记】运行Maven项目时发现项目Build错误
  6. MySQL出现:ERROR 3 (HY000): Error writing file '/tmp/MYbEd05t' (Errcode: 28)
  7. android——wifi系统架构
  8. web 基本概念辨异 —— URI 与 URL
  9. aes解密设置utf8 php,PHP aes (ecb)解密后乱码问题
  10. cpu核心 线程 进程_科个普:进程、线程、并发、并行
  11. ASP.NET 2.0下实现匿名用户向注册用户的迁移(上) zhuan
  12. 网络编程必读经典书籍
  13. android wps页面设置,WPS中设置纸张的方法
  14. 我设计开发的第一个产品发布了,微信小程序“集美装修效果图“
  15. [行人重识别论文阅读]无监督学习发展与小结
  16. Python处理PDF——PyMuPDF的安装与使用(1)
  17. Elasticsearch(三) Python 使用 elasticsearch 的基本操作
  18. CISSP第6/8知识点错题集
  19. 深度学习图像分类:Kaggle植物幼苗分类(Plant Seedlings Classification)完整代码
  20. 去除em斜体的方法_鱼缸水体pH值对观赏鱼的影响,以及偏高或偏低的调节方法...

热门文章

  1. C++学习之路(六):实现一个String类
  2. MP4大文件虚拟HLS分片技术,避免服务器大量文件碎片
  3. Cesium学习笔记(五):3D 模型 (http://blog.csdn.net/umgsoil/article/details/74572877)
  4. ES6之let(理解闭包)和const命令
  5. Android 高仿新浪微博底部导航栏,实现双击首页Tab,页面的ListView滚动、刷新
  6. 23种设计模式整体详解
  7. 走向.NET架构设计—第四章—业务层分层架构(后篇)
  8. c++之趣味new代码大家看
  9. java基础-迭代器(Iterator)与增强for循环
  10. Adobe Flash Player 10新特性详解:支持GPU加速