首页 > 其他分享 >快速数论变换 | NTT 初学

快速数论变换 | NTT 初学

时间:2023-12-22 22:24:17浏览次数:35  
标签:原根 数论 NTT varphi lt 初学 mod equiv

快速数论变换 | NTT 初学

前置

  • FFT

  • 原根

    阶:称满足同余方程 \(a^x\equiv 1\mod m\) 的最小正整数解 \(x\) 为 \(a\) 的模 \(m\) 的阶,记为
    \(Ord_ma\)。

    观察到本质就是最短循环节,同时该同余方程类似于欧拉定理:

    \[a^{\varphi (m)}\equiv 1\mod m,a\bot m \]

    那么显然两者的关系是 \(Ord_ma\mid \varphi(m)\)。特别地,当 \(Ord_ma=\varphi(m)\) 时,我们称 \(a\) 是 \(m\) 的一个原根。

    下面给出三个有关原根和阶的事实。

    • 若有 \(a^n\equiv 1\mod m\),则 \(a\) 的阶 \(x\) 满足 \(x\mid n\)。

      证明:

      将 \(n\) 带余除法表示成 \(xq+r(q\in Z,0\le r<x)\) 的形式,其中,\(x=Ord_ma\)。那么显然有 \(a^{xq}\equiv (a^x)^q\equiv 1^q\equiv 1\mod m\)。那么可得

      \[ a^r\equiv a^{n-xq}\equiv a^{n-xq}a^{xq}\equiv a^n\equiv 1\mod m \]

      因为 \(x\) 是满足 \(a^x\equiv 1\mod m\) 的最小正整数解,故有 \(r=0\),也即 \(n=xq\),故 \(x\mid n\)。

    • 一个数 \(x\) 是模 \(m\) 的原根当且仅当 \(x\) 可以生成所有的可逆元,也即任何与 \(m\) 互质 的整数 \(a\),\(\exists k\),\(a\equiv x^k\mod m\)。

      证明:

      若 \(x\) 不是模 \(m\) 的原根,那么其阶必定 \(<\varphi(m)\),不同于 \(x\) 的次方就少于 \(\varphi(m)\) 个,但是可逆元是数量为 \(\varphi(m)\),显然不可以生成所有可逆元。

      若 \(x\) 是模 \(m\) 的原根,\(x\) 的前 \(\varphi(m)\) 个正整数次方分别为 \(g,g^2,g^3,\cdots,g^{\varphi(m)}\)。我们尝试用反证法说明这 \(\varphi(m)\) 个数模 \(m\) 的结果互不相同。假设存在 \(1\le i<j\le \varphi(m)\) 满足 \(g^i\equiv g^j\mod m\)。那么必定有 \(g^{j-i}\equiv 1\),因为 \(j-i<\varphi(m)\),显然与 \(Ord_mx=\varphi(m)\) 矛盾。

      所以有 \(x\) 前 \(\varphi(m)\) 次方对 \(m\) 取模的余数恰好是与 \(m\) 互质的 \(\varphi(m)\) 个余数的重排后的结果,并且有 \(g^{\varphi(m)}=1\mod m\)。

    • 设 \(x\) 是模 \(m\) 的一个原根,那么 \(x^k\) 是原根,当且仅当 \(\gcd(k,\varphi (m))=1\)。

      证明:

      当 \(k\) 与 \(\varphi(m)\) 互质时,一定可以找到一组 \((a,b)\) 满足 \(ak+b\varphi(m)=1\)。故对于 \(x\) 任意次方 \(x^i\) 都有:

      \[x^i\equiv x^{i(ak+b\varphi(m))}\equiv(x^k)^{ai}\mod m \]

      也即,\(x^i\) 在同于意义下可以表示成 \(x^k\) 的 \(ai\) 次方,这说明 \(x^i\) 可生成所有可逆元,故 \(x^i\) 为模 \(m\) 的逆元。

    原根的存在性:
    原根存在的充要条件是模数能表示成 \(2,4,p^n,2p^n\),其中 \(p\) 是一个奇质数。其数量为 \(\varphi(\varphi(m))=\varphi(m-1)\)。

    原根要怎么求?由前面有关原根的事实可知,要判断一个数 \(x(1<x<m)\) 是否是 \(m\) 的原根,将 \(m - 1\) 质因数分解成 \(p_1^{c_1}p_2^{c_2}\cdots p_k^{c_k}\)。那只需要检验 \(\tfrac{x(m-1)}{p_1},\tfrac{x(m-1)}{p_2},\cdots,\tfrac{x(m-1)}{p_k}\) 中是否存在一个数 \(v\) 使得 \(v\equiv 1\mod x\)。时间复杂度 \(O(k\log m)\),其中 \(k\) 为 \(m-1\) 的质因子个数。当 \(m<10^{18}\) 时,\(k\le 25\),时间开销极小。

NTT

快速傅里叶变换中选定单位根做多项式乘法,其劣势在于无法保证浮点数的精度。考虑用原根替换,会发现它依然满足单位根的三个引理:消去引理、折半引理、求和引理。

void NTT(int *e, int op) {
  for(int i = 0; i < lim; i++) {
		if(i < p[i]) swap(e[i], e[p[i]]); // 蝴蝶变换
	}
	for(int k = 1; k < lim; k <<= 1) { // 迭代
		long long pw = Pow((op == -1 ? Pow(3, Mod - 2) : 3), (Mod - 1) / (k << 1)); // 原根替换单位根
		for(int i = 0; i < lim; i += k << 1) { 
			for(int j = i, o = 1; j < i + k; j++, o = o * pw % Mod) {
				int x = e[j];
				int y = e[j + k];
				e[j] = (x + y * o % Mod) % Mod;
				e[j + k] = (x - y * o % Mod + Mod) % Mod;
			}
		}
	}
	if(op == -1) {
		for(int i = 0; i < lim; i++) {
			e[i] = e[i] * Pow(lim, Mod - 2) % Mod;
		}
	}
}

FFT/NTT 匹配字符串

现有文本串 \(s\), 模式串 \(t\),长度分别为 \(ls\),\(lt\)。规定下标均从 \(0\) 开始。为方便处理,先要将字符串都转成整数。

设 \(t\) 与 \(s\) 在 \(s\) 的下标 \(p\) 结尾处匹配上,也即对于 \(i=0\sim lt - 1\),有 \(s_{p-lt+i+1}=t_i\)。

因为完全匹配,所以有

\[\sum\limits_{i=0}^{lt-1}(s_{p-lt+i+1}-t_i)^2=0 \]

\[\sum\limits_{i=0}^{lt-1}(s_{p-lt+i+1}^2 +t_i^2-2s_{p-lt+i+1}t_i)=0 \]

为了统一下标,将 \(t\) 反转。

\[\sum\limits_{i=0}^{lt-1}(s_{j}^2 +t_i^2-2s_{j}t_i)=0,(i+j=p) \]

这样就可以用FFT/NTT 求解了。

标签:原根,数论,NTT,varphi,lt,初学,mod,equiv
From: https://www.cnblogs.com/ereoth/p/17922454.html

相关文章

  • Codeforces Round 651 (Div. 2)C. Number Game(数学思维数论)
    C.NumberGame我们考虑那些状态是必胜态我的回合时n为奇数(除1外),直接除以n则必胜下面偶数的情况稍复杂偶数我们能进行的操作只有除以一个奇数,需要考虑怎么把当前状态变为对手的必败态偶数一定含2的因子,\(n=2^k*q,q为奇数\)当\(k=1时如果q\)是一个质数那么只能除一次q这样......
  • 基础数论
    目录质数质因数分解约数\(gcd\)求最大公约数质数质因数分解算术基本定理:\(任何一个大于1的正整数都能唯一分解为有限个质数的乘积,可以写作:\)\[N=p_1^{c_1}p_2^{c_2}...p_m^{c_m}\]\(其中c_i都是正整数,p_i都是质数,且满足p_1<p_2<...<p_m\)intprimes[N],cnt[N],m;voiddi......
  • 绘图神器PantTool SAI帮你轻松画出精美作品!
    PantoolSAI(绘图软件)是一款功能强大且易于使用的图形绘制工具,适用于各种领域的创作者,包括漫画、插画、动画、设计等。它具有丰富的绘图工具和功能,可以帮助用户快速高效地创作出高质量的图形作品。点击获取PantToolSAIPantoolSAI具有多种独特的绘图工具,包括画笔、铅笔、喷枪......
  • 初学GO
    完整代码在文章最下方view这是一个客户信息管理系统的代码,主要分为三层:view,service和model。其中,view层负责用户界面的显示和输入,service层负责业务逻辑的实现,model层负责数据的存储和操作。下面我来一步一步讲解这段代码。首先是导入包:import( "fmt" "study/model" ......
  • 网络入门初学第二期
    不知不觉就把IA的基础学了个大概,经过上一期的学习,感觉对于网络设备的工作原理还是需要一个简单的总结下面我们会根据设备内部的工作机制进线学习首先我们上一期也谈到了交换机的工作原理:接受到数据帧,查看目标MAC,对应的端口转发就ok了不过上期讲的比较模糊,这期我们就从PC如何......
  • 《初学C语言第33天》
    ////——————————————————————scanf的语法并举例说明////scanf是C语言中的一个标准输入函数,用于获取用户输入的数据,并赋值给变量。////——————基本语法:////scanf(format,variables);////其中,format是格式控制字符串,用于指定输入数据的格式,variable......
  • 《初学C语言第32天》
    //////——————————————————10.指针笔试题//////笔试题1//#include<stdio.h>//intmain()//{//  inta[5]={1,2,3,4,5};//  int*ptr=(int*)(&a+1);//  printf("%d,%d",*(a+1),*(ptr-1));//*(a+1):指的是数组a中第二个元素2......
  • pinia初学习
    pinia两种写法定义pinia第一种:对象形式不需要写refstate直接就是响应式数据import{defineStore}from"pinia"exportconstuseCounterStore=defineStore("useCounterStore",{state:()=>{return{}},actions:{......
  • 《初学C语言第30天》
    ////////————————9.指针和数组笔试题解析////一维数组,数组名的理解,指针的运算与指针类型的意义//#include<stdio.h>//intmain()//{//元素的大小:元素所占内存空间的大小// inta[]={1,2,3,4};//由初始化内容可知数组元素个数为4字节// printf("%d\n",sizeof(a)......
  • Educational Codeforces Round 159 (Rated for Div. 2) C. Insert and Equalize (贪心+
    EducationalCodeforcesRound159(RatedforDiv.2)C.InsertandEqualize思路:首先对\(a\)进行排序,然后对所有差值取gcd,获得可用的最大因子\(gc\),答案有两种情况:一种是\(a_{n+1}\)在$a_1\(~\)a_n$范围内,这时要获得最大的位置一种情况是$a_1\(~\)a_n$......