多项式(2)— 快速数论变换(NTT)
前言
前置知识:
阶、原根、离散对数;
多项式(1)— 快速傅里叶变换(FFT)。
FFT 已经能很好的在 O(nlogn)O(n\log n)O(nlogn) 内解决卷积问题,但是 FFT 用到的单位根和三角函数有关,只能采用浮点数储存,必定会带来精度误差。
我们尝试不在复数域内,而是在模剩余系内寻求一种新的单位根来解决问题,这样带来了两个好处:
不再有误差(只要大小没有超出模数);
如果题目要求取模,一并可以完成取模的任务。
新型单位根
我们回看 FFT,FFT 中单位根 wnkw_n^kwnk 满足了如下性质:
wnk=(wn1)kw_n^k = \left(w_n^1\right)^kwnk=(wn1)k;
wn0,wn1,…,wnn−1w_n^0,w_n^1,\ldots,w_n^{n-1}wn0,wn1,…,wnn−1 互不相同;
wnk+n/2=−wnkw_n^{k+n/2}=-w_n^kwnk+n/2=−wnk;
这个性质可以导出 wnk mod n=wnkw_n^{k\bmod n}=w_n^kwnkmodn=wnk。
w2n2 ...
多项式(1)— 快速傅里叶变换(FFT)
多项式乘法与卷积
对于两个多项式 f(x)=∑i=0naixi,g(x)=∑i=0nbixif(x)=\sum_{i=0}^na_ix^i,g(x)=\sum_{i=0}^nb_ix^if(x)=∑i=0naixi,g(x)=∑i=0nbixi,如果要求出乘积多项式 fgfgfg,朴素实现是 O(n2)O(n^2)O(n2) 的。但是,利用 FFT,我们可以在 O(nlogn)O(n\log n)O(nlogn) 时间内完成这一问题。
从另一个角度来理解,多项式的乘法是一种加法卷积。
对于两个序列 {a0,a1,…,an},{b0,b1,…,bn}\{a_0,a_1,\ldots,a_n\},\{b_0,b_1,\ldots,b_n\}{a0,a1,…,an},{b0,b1,…,bn},定义其卷积 {c0,c1,…,c2n}\{c_0,c_1,\ldots,c_{2n}\}{c0,c1,…,c2n},ck=∑i+j=kaibjc_k = \sum_{i+j=k}a_ib_jck=∑i+j=kaibj。
不难发现 {an},{bn}\{a_n\},\{ ...
欧拉函数与欧拉反演
欧拉函数
定义 φ(n)\varphi(n)φ(n) 表示 1∼n1\sim n1∼n 中与 nnn 互质的数个数。
形式化地讲, φ(n)=∑i=1x[gcd(i,n)=1]\varphi(n)=\sum_{i=1}^{x}[\gcd(i,n)=1]φ(n)=∑i=1x[gcd(i,n)=1],其中 [⋅][\cdot][⋅] 表示艾佛森括号。
性质 1
φ(pk)=pk−pk−1\varphi(p^k)=p^k-p^{k-1}φ(pk)=pk−pk−1,其中 ppp 为质数。
证明:
1∼pk1\sim p^k1∼pk 中恰有 pk−1p^{k-1}pk−1 个 ppp 的倍数,只有他们与 pkp^kpk 不互质。
即 φ(pk)=pk−pk−1\varphi(p^k)=p^k-p^{k-1}φ(pk)=pk−pk−1。
性质 2
欧拉函数是积性函数。
也就是说,对于互质 a,ba,ba,b,φ(ab)=φ(a)φ(b)\varphi(ab)=\varphi(a)\varphi(b)φ(ab)=φ(a)φ(b)。
证明:
引理1:xxx 与 ababab 互质的充要条件是 x ...
离散变量取值问题的最小割建模
离散变量取值问题
有若干个变量,每个变量取值为 v1,v2,…,vnv_1,v_2,\ldots,v_nv1,v2,…,vn,现在要求所有变量的和最小(大),且不同变量的取值有某种限制。(详细见下文例题)
先不考虑限制,考虑用最小割刻画这个问题。
如图所示,对每一个变量都建立 n+1n+1n+1 个点 X1,X2,…,Xn+1X_1, X_2, \ldots, X_{n+1}X1,X2,…,Xn+1:
从 SSS 到 X1X_1X1 建立一条边权为 ∞\infty∞ 的边;
从 Xn+1X_{n+1}Xn+1 到 TTT 建立一条边权为 ∞\infty∞ 的边;
从 XiX_{i}Xi 到 Xi+1X_{i+1}Xi+1 建立一条边权为 viv_{i}vi 的边;
从 Xi+1X_{i+1}Xi+1 到 XiX_{i}Xi 建立一条边权为 ∞\infty∞ 的边。
这样我们保证了,每个变量所构造出的一条链上,在最小割中有且仅有一条边被割掉,被割掉的边的边权就代表了我们为这个变量的取值。
证明:
存在性:
如果没有边被割,那么显然存在 S→TS\to ...
[ARC068E] Snuke Line 解题报告
题意
[ARC068E] Snuke Line
给定 nnn 个区间 [li,ri] (1≤li≤ri≤m)[l_i,r_i]\ (1\le l_i \le r_i \le m)[li,ri] (1≤li≤ri≤m)。
对 1∼m1\sim m1∼m 中的每一个 iii,求出存在一个 iii 的倍数在其中的区间个数。
解法 1(整除分块)
我们发现,对于一个 ddd 来说,[l,r][l,r][l,r] 中有 ddd 的倍数的充要条件是 ⌊l−1d⌋≠⌊rd⌋\left \lfloor \dfrac{l-1}{d} \right \rfloor \neq \left \lfloor \dfrac{r}{d} \right \rfloor⌊dl−1⌋=⌊dr⌋。
略证:
(引理)⌈xy⌉=⌊x−1y⌋+1\left \lceil \dfrac{x}{y} \right \rceil = \left \lfloor \dfrac{x-1}{y} \right \rfloor +1⌈yx⌉=⌊yx−1⌋+1。
证明:设 x=ky+bx=ky+bx=ky+b,其中 ...
拉格朗日插值法
拉格朗日插值法
过 n+1n+1n+1 个横坐标互异的点 (x1,y1),(x2,y2),⋯ ,(xn+1,yn+1)(x_1,y_1),(x_2,y_2),\cdots,(x_{n+1},y_{n+1})(x1,y1),(x2,y2),⋯,(xn+1,yn+1) 的 nnn 次多项式恰为
f(x)=∑i=1n+1yi∏j≠ix−xixj−xif(x) = \sum_{i=1}^{n+1} y_i \prod_{j\neq i} \dfrac{x-x_i}{x_j-x_i}
f(x)=i=1∑n+1yij=i∏xj−xix−xi
证明
将 n+1n+1n+1 个点代入显然得到结论。
模板
[洛谷P4781] 【模板】拉格朗日插值
给出 nnn 个点,插值出多项式,并求出一个点值,朴素实现是 O(n2)O(n^2)O(n2) 的。
如果要在取模下实现,记得先把分母都乘起来,然后统一求逆元,这样复杂度依然是 O(n2)O(n^2)O(n2)的。
参考代码:
12345678910111213141516171819202122232425262728293031 ...
OI 中有用的 shell 脚本
shell 脚本介绍
略。看下面的代码自行意会
一键测试所有样例
123456789101112131415name=problemg++ $name.cpp -o $name -std=c++14 -Wallfor i in {1..10}do cp $name$i.in $name.in time ./$name diff $name.out $name$i.out -Z > /dev/null if (($?)) then echo 样例 $i 不通过 else echo 样例 $i 通过 fidone
注意这里的 -Z 开关可以自行调整。 $? 指的是上一个命令的返回值。
对拍
12345678910111213141516g++ gen.cpp -o geng++ std.cpp -o stdg++ my.cpp -o mywhile truedo ./gen ./std ./my diff out ans -Z if (($?)) then ...
点分治、边分治
点分治
淀粉质
常见题目套路:求出具有某一条件的路径个数/求出一条最优的路径
核心思路是:每次选取一个点 uuu ,统计所有经过这个点的路径,然后把这个点删去,对于剩下的森林执行同样的操作。
如何统计?所有经过点 uuu 的路径分成 3 部分,v1−u−v2v_1 - u - v_2v1−u−v2,其中 v1,v2v_1,v_2v1,v2 不在同一个子树之中,然后每个点存储需要的信息,最后合并。
统计完点 uuu 后,把它从整颗树里面删去,以后不需要用到它了。
如果每次选取的点都是子树的重心,那么复杂度就能够达到 O(nlogn)O(n \log n)O(nlogn)。
总结一下,就是如下流程:
对于一颗树 TTT:
找到重心作为根。
对每个子树,依次进行如下 3 步操作:
i) dfs 求出每个子树的到当前根的信息;
ii) 对于子树的所有节点,与前面的子树的信息进行合并求解答案;
iii) 将这个子树节点的所有信息合并。
删去根。
对于根的每一个子树,回到第 111 步,直到只剩下一个节点。
信息究竟是什么意思呢?
举个例子,求树的直径。(这是上文说的求出一条最优的 ...
阶、原根、离散对数
本文中,若无特殊说明,mmm 代表正整数,ppp 代表质数。
事实上,在题目中我们大多数情况下都是讨论对质数取模的情况。
阶
定义
若 (a,m)=1(a,m)=1(a,m)=1,满足 an=1(modm)a^n = 1 \pmod man=1(modm) 的最小的 nnn 称为 aaa 模 mmm 的阶,记作 δma\delta_m aδma。
如果 (a,m)=1(a,m)=1(a,m)=1 不互质,那么不难发现,不存在 nnn,使得 an=1(modm)a^n = 1 \pmod man=1(modm),故我们不定义 aaa 模 mmm 的阶。
性质
本节中 a,ba,ba,b 均与 mmm 互质。
a,a2,…,aδmaa,a^2,\ldots,a^{\delta_m a}a,a2,…,aδma 模 mmm 两两不同。 【引理 1】完全剩余系中与 mmm 互质的剩余类所构成的系称为缩系,缩系内四则运算均封闭。
(证明略)
性质 1 证明:
用反证法,假设存在 1≤i<j≤δma1\le i < j \le \delta_m a1≤i<j≤δma,使 ...
莫比乌斯反演
数学 = 恐怖
莫比乌斯函数
μ\muμ 为莫比乌斯函数,定义为
μ(n)={1n=10n 含有平方因子(−1)kk 为 n 的本质不同质因子个数\mu(n)= \begin{cases} 1&n=1\\ 0&n\text{ 含有平方因子}\\ (-1)^k&k\text{ 为 }n\text{ 的本质不同质因子个数}\\ \end{cases}
μ(n)=⎩⎨⎧10(−1)kn=1n 含有平方因子k 为 n 的本质不同质因子个数
—— 引自 OI wiki
筛法求莫比乌斯函数
考虑 nnn 最小质因数为 ppp,n/p=n′n/p=n'n/p=n′。
若 n′ mod p=0n' \bmod p = 0n′modp=0, μ(n)=0\mu(n)=0μ(n)=0。(含有平方因子)
否则,μ(n)=−μ(n′)\mu(n)=-\mu(n')μ(n)=−μ(n′)。(分类讨论几种情况就能发现)
参考代码:
123456789101112int mu[N],pri[N],cnt;bool not_prime[N];mu[1]=1 ...