zoukankan      html  css  js  c++  java
  • 学习NTT(快速数论变换)小记

    前言

    以前一直知道FFT的这个思想,一直没有实现。
    本想着转C语言抛弃P语言后就码一码。
    但最近遇到了奇怪的题目,要用到NTT。
    于是就学了一发,借着各种板子好歹是学会了。

    简介

    NTT是什么?
    其实就是FFT,一样是求多项式卷积之类的东东。只不过没有利用到复数里面单位根的性质。
    有什么用?
    可以实现取模操作!

    具体操作

    原根:

    百度百科的欧拉函数比较费解。
    其实解释起来就是对于一个数P
    g是它的原根当且仅当g满足:
    x(0<=x<P1)gxmod P对于任意的x(0<=x<P-1)g^xmod P互不相同
    根据这个玩意儿,很容易判断出一个数g是不是P的原根。
    显然:当P是一个质数时,一定有原根。
    对于原根,都比较难找(只能暴力),但对于一个质数的原根,都很小。
    比如998244353,1004535809,469762049这三个数的原根为3.

    原根的用处:

    我们看到之前FFT里面的单位根:ωniomega_n^i
    我们直接把上面这个单位根替换成原根即可。
    怎么替换?
    ωni=gi(mo1)nmoomega_n^i=g^{i*lfloorfrac{(mo-1)}n floor}(mo是模数)
    直接套上FFT板子即可。

    为什么:

    我们知道,FFT是利用单位根的几个重要性质来加速的。
    那么换成原根之后,只需要满足单位根那几个性质就可以了。
    怎么满足呢?

    我们知道,单位根满足:
    1、全部都不相同
    2、ωnxωny=ωnx+y=ωn(x+y)modnomega_n^xomega_n^y=omega_n^{x+y}=omega_n^{(x+y)mod n}
    然后利用这两个性质推出其他性质。

    那么原根是否也可以呢?
    1、gi(mo1)ng^{i*lfloorfrac{(mo-1)}n floor}这个玩意儿右边是一样的,左边的i是不定的。
    而且这个g由于是原根,模mo的意义下是都不同的。
    得证
    2、这个性质其实对模数要求很高。
    比如这个模数:1004535809(479 * 2 ^21 + 1)
    我们发现,这个模数就很棒,对于一个比较大的n(2的某次方)可以整除。
    那么可以容易消去下取整。
    接下来就好搞了:
    gx(mo1)ngy(mo1)ng^{x*frac{(mo-1)}n}*g^{y*frac{(mo-1)}n}
    容易变成:
    (gx)(mo1)n(gy)(mo1)n(g^x)^{frac{(mo-1)}n}*(g^y)^{frac{(mo-1)}n}
    (g(x+y))(mo1)n{(g^{(x+y)})}^frac{(mo-1)}n
    已知:
    (gn)(mo1)n=gmo1{(g^{n})}^frac{(mo-1)}n=g^{mo-1}
    根据费马小定理:gmo1=1g^{mo-1}=1
    所以说:(g(x+y))(mo1)n=(g(x+y)mod n)(mo1)n{(g^{(x+y)})}^frac{(mo-1)}n={(g^{(x+y)mod n})}^frac{(mo-1)}n
    那么就意味着可以利用原根来代替单位根搞了。

    其他什么性质就不推了。

    应用(板子)

    我们发现,NTT与FFT的流程、时间都是一样的。
    这玩意似乎很棒,比起FFT有以下优点:
    1、可以取模
    2、避免FFT的精度问题

    但是,有优点也有缺点:
    1、模数通常很头疼(为什么可以往下翻)
    2、常数大(可能是我不会卡常)

    一个套路——通常看到一个卷积的形式并且模数为:998244353,1004535809,469762049时,可以考虑NTT了。

    板子放在例题里了,自己去看
    洛谷P3803 【模板】多项式乘法(FFT)(话说这题我NTT还TLE了)
    JZOJ3303. 【集训队互测2013】城市规划(时限良心)

    拓展

    有时候NTT模数不得,怎么办?
    据说可以利用上面的三个模数搞,搞完后用中国剩余定理。
    (据说还有很恶心的题,然鹅我没有做多少)

  • 相关阅读:
    怎样克服 JavaScript 框架疲劳?
    jQuery 简单归纳总结
    锋利的JQuery —— 事件和动画
    锋利的JQuery —— DOM操作
    锋利的JQuery —— 选择器
    Maven日常 —— 你应该知道的一二三
    《时间简史》—— 读后总结
    Elasticsearch之_default_—— 为索引添加默认映射
    Elasticsearch 动态映射——自动检测
    安装了Node.js 从VScode 使用node -v 和 npm -v等命令却无效
  • 原文地址:https://www.cnblogs.com/RainbowCrown/p/11148346.html
Copyright © 2011-2022 走看看