【Learning】多项式的一些东西
FFT
坑
NTT
将\(FFT\)中的单位复数根改成原根即可。
卡常版NTT模版
struct Mul
{ int Len;
int wn[N], Lim;
int rev[N];
inline void getReverse(int * a)
{
static int rev[N];
rev[0] = 0;
for (register int i = 0; i < Len; i++)
{
rev[i] = (rev[i>>1] >> 1) | ((i&1) ? (Len >> 1) : 0);
if (i < rev[i]) swap(a[i], a[rev[i]]);
}
}
void NTT(int * a, int opt)
{
getReverse(a);
for (register int i = 0; i < Len; i += 2)
{
int x = a[i], y = 1LL * wn[0] * a[i + 1] % mod;
a[i] = Plus(x, y), a[i + 1] = Minus(x, y);
}
for (register int i = 0; i < Len; i += 4)
{
int x1 = a[i], y1 = 1LL * wn[0] * a[i + 2] % mod;
int x2 = a[i + 1], y2 = 1LL * wn[Lim / 2] * a[i + 3] % mod;
a[i] = Plus(x1, y1), a[i + 2] = Minus(x1, y1);
a[i + 1] = Plus(x2, y2), a[i + 3] = Minus(x2, y2);
}
for (register int i = 8; i <= Len; i <<= 1)
{
int M = i >> 1;
for (register int j = 0; j < Len; j += i)
{
for (register int k = 0; k < M; k += 4)
{
int x1 = a[j + k], y1 = 1LL * wn[Lim / M * k] * a[j + k + M] % mod;
int x2 = a[j + k + 1], y2 = 1LL * wn[Lim / M * (k+1)] * a[j + k + M + 1] % mod;
int x3 = a[j + k + 2], y3 = 1LL * wn[Lim / M * (k+2)] * a[j + k + M + 2] % mod;
int x4 = a[j + k + 3], y4 = 1LL * wn[Lim / M * (k+3)] * a[j + k + M + 3] % mod;
a[j + k] = Plus(x1, y1), a[j + k + M] = Minus(x1, y1);
a[j + k + 1] = Plus(x2, y2), a[j + k + M + 1] = Minus(x2, y2);
a[j + k + 2] = Plus(x3, y3), a[j + k + M + 2] = Minus(x3, y3);
a[j + k + 3] = Plus(x4, y4), a[j + k + M + 3] = Minus(x4, y4);
}
}
}
if (opt == -1)
{
for (register int i = 0; i < Len; i++)
a[i] = 1LL * a[i] * inv[Len] % mod;
for(register int i = 1; i < Len; i++)
if(i < Len-i) swap(a[i], a[Len-i]);
}
}
inline void init()
{
Lim = Len;
wn[0] = 1; wn[1] = power(7, (mod-1) / (Len << 1), mod);
for (int i = 2; i < (Len << 1); i++) wn[i] = 1LL * wn[i-1] * wn[1] % mod;
}
inline int getLen(int l)
{
for (Len = 1; Len <= l; Len <<= 1);
return Len;
}
};
多项式求逆
也就是求
\]
假设我们已知
\]
两式相减得
\]
\]
\]
两边同时乘上\(A(x)\)
\]
因为\(A(x)B(x) = 1\), 所以可以得到
\]
\]
就这样解决了
时间复杂度为\(T(n) = T(\frac{n}{2}) +O(n \log n)\)
代码
inline void getInv(int * A, int * B, int len)
{
static int tmp1[N], tmp2[N];
B[0] = power(A[0], mod-2, mod);
for (register int k = 2; k <= len; k <<= 1)
{
int Len = k << 1;
cpy(tmp1, A, k, Len);
cpy(tmp2, B, (k >> 1), Len);
Calc.Len = Len;
Calc.NTT(tmp1, 1);
Calc.NTT(tmp2, 1);
for (int i = 0; i < Len; i++)
tmp1[i] = Minus(Plus(tmp2[i], tmp2[i]), 1LL * tmp1[i] * tmp2[i] % mod * tmp2[i] % mod);
Calc.NTT(tmp1, -1);
cpy(B, tmp1, k, Len);
}
return;
}
多项式开根
也就是求
\]
假设我们已知
\]
两式相减得
\]
然后平方一下
\]
\]
配一下方
\]
\]
\]
因为\(A(x)B(x) = 1\), 所以可以得到
\]
为了方便实现,我们常把它化成
\]
然后就解决了
时间复杂度为\(T(n) = T(\frac{n}{2}) + O(n \log n) = O(n \log n)\)
多项式求导
模拟即可
代码
inline void getDeri(int * a, int len)
{ for (register int i = 0; i < len; i++)
a[i] = 1LL * a[i+1] * (i+1) % mod;
}
多项式积分
模拟即可
代码
inline void getInte(int * a, int len)
{ for (int i = len-1; i >= 1; i--)
a[i] = 1LL * a[i-1] * inv[i] % mod;
a[0] = 0;
}
多项式求\(\ln\)
已知多项式\(A(x)\), 求\(B(x) = \ln (A(x))\)
根据链式法则, 我们可以得到
\]
所以
\]
代码
void getLn(int * A, int len)
{
static int tmp1[N], tmp2[N], tmp3[N];
int Len = len << 1;
cpy(tmp1, A, len, Len);
cpy(tmp2, A, len, Len);
getDeri(tmp1, len);
getInv(tmp2, tmp3, len);
Calc.Len = Len;
Calc.NTT(tmp1, 1);
Calc.NTT(tmp3, 1);
for (int i = 0; i < Len; i++)
tmp1[i] = 1LL * tmp1[i] * tmp3[i] % mod;
Calc.NTT(tmp1, -1);
memset(tmp1 + len, 0, 4 * (Len - len));
getInte(tmp1, len);
cpy(A, tmp1, len, Len);
}
时间复杂度还是\(T(n) = T(\frac{n}{2}) + O(n \log n) = O(n \log n)\)
牛顿迭代
我们要求\(f(x) = 0\)的根
那么可以使用泰勒公式来近似\(f(x) = 0\)的根
我们设当前的近似值是\(x_{n}\), 我们想要得到的近似值是\(x_{n+1}\)
截取泰勒公式的线性部分: $$f(x_{n}) + f'(x_{n})(x_{n+1}-x_n) = 0$$
解方程得: $$x_{n+1} = x_n - \frac{f(x_{n})}{f'(x_{n})}$$
我们可以用这种方法来解多项式方程。
多项式\(\exp\)
我们要求的是 \(exp(A(x))\), 这相当于解一个方程: \(g(exp(A(x))) = \ln(exp(A(x))) - A(x) = 0\)
可以直接套用牛顿迭代法求解。
【Learning】多项式的一些东西的更多相关文章
- FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅰ
众所周知,tzc 在 2019 年(12 月 31 日)就第一次开始接触多项式相关算法,可到 2021 年(1 月 1 日)才开始写这篇 blog. 感觉自己开了个大坑( 多项式 多项式乘法 好吧这个 ...
- FFT是个啥?
简单来说就是一个计算多项式乘法的东西呀.. 以下内容基本都是在大黑书<算法导论>上的.. 总述 对于项数为$n$的多项式$A(x)$和项数为$m$的多项式$B(x)$,可以如此表达: $$ ...
- 【BZOJ3625】【CF438E】小朋友和二叉树
题目 传送门 思路&做法 我们可以用\(v_i\)表示\(i\)在\(c\)中出现了几次, 用\(f_i\)表示权值为\(i\)的神犇树的总数, 于是 \[ f_x = \sum_{i = 0 ...
- 【learning】多项式乘法&fft
[吐槽] 以前一直觉得这个东西十分高端完全不会qwq 但是向lyy.yxq.yww.dtz等dalao们学习之后发现这个东西的代码实现其实极其简洁 于是趁着还没有忘记赶紧来写一篇博 (说起来这篇东西的 ...
- 【learning】多项式相关(求逆、开根、除法、取模)
(首先要%miskcoo,这位dalao写的博客(这里)实在是太强啦qwq大部分多项式相关的知识都是从这位dalao博客里面学的,下面这篇东西是自己对其博客学习后的一些总结和想法,大部分是按照其博客里 ...
- 【Learning】 多项式的相关计算
约定的记号 对于一个多项式\(A(x)\),若其最高次系数不为零的项是\(x^k\),则该多项式的次数为\(k\). 记为\(deg(A)=k\). 对于\(x\in(k,+ \infty)\),称\ ...
- 【Learning】多项式乘法与快速傅里叶变换(FFT)
简介: FFT主要运用于快速卷积,其中一个例子就是如何将两个多项式相乘,或者高精度乘高精度的操作. 显然暴搞是$O(n^2)$的复杂度,然而FFT可以将其将为$O(n lg n)$. 这看起来十分玄学 ...
- 【learning】多项式开根详解+模板
概述 多项式开跟是一个非常重要的知识点,许多多项式题目都要用到这一算法. 用快速数论变换,多项式求逆元和倍增法可以在$O(n log n)$的时间复杂度下求出一个$n$次多项式的开根. 前置技能 快速 ...
- Machine Learning Algorithms Study Notes(4)—无监督学习(unsupervised learning)
1 Unsupervised Learning 1.1 k-means clustering algorithm 1.1.1 算法思想 1.1.2 k-means的不足之处 1 ...
随机推荐
- python之字典 2014-4-5
#字典:当索引不好用时1.字典 类似于php的关联数组 列表类似于索引数组 2.创建字典 phonebook={'alice':'2100','tom':'1900'} 键值之间用: 项之间用, 空字 ...
- POJ1308/HDU1325/NYOJ129-Is It A Tree?,并查集!
Is It A Tree? Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 28838 Accepted: 9843 -& ...
- POJ-20407Relatives/NYOJ-333mdd的烦恼,欧拉函数简单应用,模板A
poj Relatives Time Limit: 1000MS Memory Li ...
- Web 后端编程的几个关键点(总结中...)
基础 服务端结构 服务器如何部署,负载均衡,代理技术,如何向B端提供服务? 分布式架构 与前端界面的交互形式 数据 CURD 表之间的关联 较为棘手 如何将一对多 多对多的概念进行 面向对象 描述 前 ...
- P2819 图的m着色问题 洛谷
https://www.luogu.org/problem/show?pid=2819 题目背景 给定无向连通图G和m种不同的颜色.用这些颜色为图G的各顶点着色,每个顶点着一种颜色.如果有一种着色法使 ...
- codevs——1742 爬楼梯
1742 爬楼梯 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 小明家外面有一个长长的楼梯,共N阶.小明的 ...
- CDOJ1339 郭大侠与线上游戏(维护一个set中的中位数——平衡树/双set)
http://acm.uestc.edu.cn/#/problem/show/1339 题意:有三种操作,分别是. 1.向队列推入一个数x. 2.弹出这个队列的第一个数字 3.查询这个队列的中位数是多 ...
- springboot+idea+maven学习第一天(springboot入门,idea整合maven)
1.springboot简介 简化Spring 用用开发的一个框架: 真个S僻壤技术栈的一个大整合 j2ee开发的一站式解决方案 2.微服务 微服务:是一种架构风格 一个应用应该是一组小型服务:可以通 ...
- 条款十六: 在operator=中对所有数据成员赋值
当涉及到继承时,派生类的赋值运算符也必须处理它的基类成员的赋值!否则,当派生类对象向另一个派生类对象赋值时,只有派生类部分赋值了.看看下面: class base { public: ): x(ini ...
- 【剑指Offer学习】【面试题31:连续子数组的最大和】
题目:输入一个整型数组,数组里有正数也有负数.数组中一个或连续的多个整数组成一个子数组.求全部子数组的和的最大值.要求时间复杂度为O(n). 样例说明: 比如输入的数组为{1, -2, 3, 10, ...