首页 > 其他分享 >【学习笔记】数论杂谈

【学习笔记】数论杂谈

时间:2024-01-17 18:58:32浏览次数:23  
标签:right frac 数论 sum 杂谈 笔记 int le omega

一. 素数相关

0. 约定

若无特殊说明,本部分做以下记号规定。

\(p\in \mathbb{P}\),\(\mathbb P\) 为质数集。

\(\pi(n)\) 表示 \(1\) 至 \(n\) 内的素数个数。

\(P^{+}(n),P^-(n)\) 分别表示 \(n\) 的最大/最小质因子。

\(\nu_i\) 表示 \(i\) 的可重质因子个数。

1. 素数定理

\[\pi(x)\sim \frac x{\ln x} (x\rightarrow+\infty) \]

\[\exists 0<a<b,\quad s.t.\frac {ax}{\ln x}<\pi (x)<\frac {bx}{\ln x} \]

常用于估算素数数组大小。

2. 筛法

埃氏筛不展开。

欧拉筛保证合数只被筛一次,复杂度 \(O(n)\)。即线性筛。

同时通过欧拉筛容易实现对于欧拉函数,莫比乌斯函数的预处理。

3. 判断素数

  1. 暴力。

暴力的 \(O(\sqrt n)\) 是一种准确素性测试算法的复杂度。

  1. \(\text{Miller-Rabin}\) 算法

Miller-Rabin 使用费马小定理和二次探测定理进行素性测试。

显然根据费小和二次探测有

\[a^{p-1}\equiv 1\pmod p \]

\[\forall x^2\equiv 1\pmod p, x\equiv\pm 1\pmod p \]

设需要检验素性的数为 \(x\)。取 \(y<x\),那若 \(x\) 为质数则 \(y^{x-1}\equiv 1\pmod x\)。

再令 \(x-1=t\times 2^k\)。

根据二次探测定理,考虑对 \(y^{t\times 2^k}\) 不断开方,有

\[\exists 0\leq k'<k,y^{t\times 2^{k'}}\equiv-1\pmod x \]

或 \(y^t\equiv 1\pmod x\)。

我们如此地对于 \(x\) 进行 \(m\) 次测试,复杂度是 \(O(m\log^3x)\)。但当然这是个概率算法。

一组常用的底数是 \(\{2,3,7,61,24251\}\)。在 \(10^{16}\) 内仅 \(46856248255981\) 发生误判。

#define int long long
int base[15]={0,2,3,7,61,24251};
inline bool Miller_Rabin(int n){
	if(n<2||n==46856248255981ll)return false;
	int t=n-1,k=0;
	while(t%2==0){
		t>>=1;
		k++;
	}
	for(int i=1;i<=5&&base[i]<n;i++){
		int x=qpow(base[i],t);
		if(x==1)continue;
		for(int j=1;j<k;j++)if(x!=n-1)x=(x*x)%n;
		if(x!=n-1)return false;
	}
	return true;
}

4. \(\text{Meissel-Lehmer}\) 算法求 \(\pi (n)\)

以下令 \(p_i\) 表示第 \(i\) 个素数。\(p_1=2\)。

定义 \(\psi_i(n)=\sum\limits_{1\le x<n}[P^-(x)>p_i]\),\(\tau_i(n,k)=\sum\limits_{1\le x<n}\left([P^-(x)>p_i]\times [\nu_x=k]\right)\)。

由于容斥显然有

\[\psi_i(n)=\sum_{k\ge 0}\tau_i(n,k)[p_i^k\le n] \]

其中钦定 \(\tau_i(n,0)=1\)。

考虑对于 \(n^{\frac{1}3}\le m\le n^{\frac{1}{2}}\),其中 \(m=p_{\omega}\)。

那么对于 \(k\ge 3\) 时有 \(\tau_{\omega}(n,1)=\pi(n)-\omega\),\(\tau_{\omega}(n,k)=0\)。

\[\therefore \pi(n)=\tau_{\omega}(n,1)+\omega=\psi_{\omega}(n)-\tau_{\omega}(n,2)-\tau_{\omega}(n,0)+\omega \]

那么对于 \(\pi(n)\) 我们只需计算 \(\psi_{\omega}(n)\) 和 \(\tau_{\omega}(n,2)\) 即可。

  1. 计算 \(\tau_{\omega}(n,2)\)

考虑它的实际意义:即质数对 \((p,q)\) 满足 \(m<p\le q\) 且 \(pq\le n\) 的个数。

显然 \(p\in[m+1,\sqrt n]\),那么亦有 \(q\in[p,\frac{n}p]\),可得:

\[\tau_{\omega}(n,2)=\sum_{p\in [m+1,\sqrt n]}\left(\pi \left(\frac{n}p\right)-\pi (p-1)\right) \]

此时线性筛预处理容易做到 \(O(\frac{n}{m})\)。

  1. 计算 \(\psi_{\omega}(n)\)

通过容斥有

\[\psi_{\omega}(n)=\psi_{\omega-1}(n)-\psi_{\omega -1}\left(\frac{n}{p_{\omega}}\right) \]

边界 \(\psi_{0}(n)=[n]\)。

那么考虑 dfs 计算此式,此时复杂度难以接受。考虑对于边界加入 \(x\le m\) 的剪枝。

\[\psi_{\omega}(n)=\sum_{x\le m}\mu(x)\left[\frac{n}{x}\right]+\sum_{\frac{x}{P^{-}(x)}\le m<x}\mu(x)\psi_{\pi\left(P^{-}(x)\right)-1}\left(\frac{n}{x}\right) \]

\[R=\sum_{x\le m}\mu(x)\left[\frac{n}{x}\right] \]

\[T=\sum_{\frac{x}{P^{-}(x)}\le m<x}\mu(x)\psi_{\pi\left(P^{-}(x)\right)-1}\left(\frac{n}{x}\right) \]

\[\therefore \psi_{\omega}(n)=R+T \]

显然 \(R\) 容易预处理。

对于

\[T=-\sum_{p\le m}\sum_{x\le m<xp}\left[P^-(x)>p\right]\mu(x)\psi_{\pi (p)-1}\left(\frac{n}{xp}\right) \]

考虑分块计算,令

\[T_1=-\sum_{n^{\frac{1}3}<p\le m}\sum_{x\le m<xp}\left[P^-(x)>p\right]\mu(x)\psi_{\pi (p)-1}\left(\frac{n}{xp}\right) \]

\[T_2=-\sum_{n^{\frac{1}4}<p\le n^{\frac{1}3}}\sum_{x\le m<xp}\left[P^-(x)>p\right]\mu(x)\psi_{\pi (p)-1}\left(\frac{n}{xp}\right) \]

\[T_3=-\sum_{p\le n^{\frac{1}4}}\sum_{x\le m<xp}\left[P^-(x)>p\right]\mu(x)\psi_{\pi (p)-1}\left(\frac{n}{xp}\right) \]

\[\therefore T=T_1+T_2+T_3 \]

首先 \(T_3\) 显然通过树状数组枚举 \(p\) 统计对 \(\psi\) 的贡献在 \(O(\frac{n}m\log n)\)
简单实现。

对于 \(T_1,T_2\) 由于 \(n^{\frac{1}4}<p<P^-(x),x\le m\le \sqrt n\),故必有 \(x\in \mathbb P\)。

\[\therefore T_1=-\sum_{n^{\frac{1}3}<p\le m}\sum_{p<q\le m}\psi_{\pi (p)-1}\left(\frac{n}{pq}\right) \]

\[\therefore T_2=-\sum_{n^{\frac{1}4}<p\le n^{\frac{1}3}}\sum_{p<q\le m}\psi_{\pi (p)-1}\left(\frac{n}{pq}\right) \]

考虑计算 \(T_1,T_2\)。

\(T_1\) 由于 \(\frac{n}{pq}<n^{\frac{1}3}<p\) 故 \(\psi_{\pi (p)-1}\left(\frac{n}{pq}\right)=1\),所以 \(T_1\) 容易 \(O(m)\) 计算:

\[T_1=-\sum_{n^{\frac{1}3}<p\le m}\left(\pi(m)-\pi(p)\right) \]

对于 \(T_2\) 再次拆开为 \(S_1+S_2=T_2\):

\[S_1=\sum_{n^{\frac{1}{4}}<p\le n^{\frac{1}3}}\sum_{p<q\le m}\left[q\le \frac{n}{p^2}\right]\psi_{\pi(p)-1}\left(\frac{n}{pq}\right) \]

\[S_2=\sum_{n^{\frac{1}{4}}<p\le n^{\frac{1}3}}\sum_{p<q\le m}\left[q>\frac{n}{p^2}\right]\psi_{\pi(p)-1}\left(\frac{n}{pq}\right) \]

对于 \(S_1\) 由于有 \(p\le \frac{n}{pq}< \sqrt n< p^2\),故有 \(\psi_{\pi(p)-1}\left(\frac{n}{pq}\right)=\pi\left(\frac{n}{pq}\right)-\pi(p)+1\)

然后你再分为 \(S_1=Q_1+Q_2\),

\[Q_1=\sum_{n^\frac{1}{4}< p\leq n^\frac{1}{3}}(1-\pi(p))\sum_{{p< q\le m}}\left[q\leq \frac{n}{p^2}\right] \]

\[Q_2=\sum_{n^\frac{1}{4}< p\leq n^\frac{1}{3}}\sum_{{p<q\leq m }}\left[q\leq \frac{n}{p^2}\right]\pi\left(\frac{n}{pq}\right) \]

我们发现 \(Q_1\) 简单处理即可,对于 \(Q_2\) 进行类数论分块只有 \(\pi(\frac{n}{p^2})\) 块,所以保证 \(O\left(\frac{n^{\frac{2}3}}{\log n}\right)\)。

对于 \(S_2\),有 \(\sqrt{\frac{n}m}\le\sqrt{\frac{n}q}<p\) 且 \(\frac{n}{pq}<p\) 故 \(\psi_{\pi(p)-1}\left(\frac{n}{pq}\right)=1\)。

\[\therefore S_2=\sum_{\sqrt{\frac{n}{m}}<p\le n^{\frac{1}3}}\left(\pi(m)-\pi\left(\min\left\{p,\frac{n}{p^2}\right\}\right)\right) \]

复杂度 \(O(m)\)。

考虑整个过程的时间复杂度计算。令 \(m=O(n^{\frac{1}3}\log^2n)\) 时复杂度最优为 \(O\left(\frac{n^{\frac{2}{3}}}{\log n}\right)\)。

若将 \(Q_2\) 分为五个部分计算(参见oi-wiki),可优化至 \(O\left(\frac{n^{\frac{2}{3}}}{\log^2 n}\right)\)。

常数极大的代码。比最优解慢了近40s。


inline void init(){
	Getprime();
	sz[0]=1;
	for(int i=0;i<S;i++)phi[i][0]=i;
	for(int i=1;i<=2;i++){
		sz[i]=p[i]*sz[i-1];
		for(int j=1;j<S;j++)phi[j][i]=phi[j][i-1]-phi[j/p[i]][i-1];
	}
	return;
}

inline int Phi(int x,int id){
	int P=p[id],r=sz[id];
	if(!id)return x;
	if(id<=2)return phi[x%r][id]+(x/r)*phi[r][id];
	if(x<=P*P)return pi[x]-id+1;
	if(x<=P*P*P&&x<N){
		int y=sqrt2(x),t=pi[y],res=pi[x]-((t-id+1)*(t+id-2)>>1);
		for(int i=id+1;i<=t;i++)res+=pi[x/p[i]];
		return res;
	}
	return Phi(x,id-1)-Phi(x/p[id],id-1);
}

inline int Pi(int x){
	if(x<N)return pi[x];
	int X=Pi(sqrt2(x)),Y=Pi(sqrt2(sqrt2(x))),Z=Pi(sqrt3(x)),res=Phi(x,Y)+((X+Y-2)*(X-Y+1)>>1);
	for(int i=Y+1;i<=X;i++){
		int t=x/p[i];res-=Pi(t);
		if(i>Z)continue;
		int O=Pi(sqrt2(t));
		for(int j=i;j<=O;j++)res-=Pi(t/p[j])-j+1;
	}
	return res;
}

5. \(\text{Pollard-Rho}\) 算法计算非平凡因子

对于寻找合数 \(n\) 的一种非平凡因子的朴素做法显然可以枚举 \([1,\sqrt n]\) 来做到。当然你还可以通过预处理一点打表来达到 \(O(\frac{\sqrt n}{\ln n})\)。

生日悖论是一个著名的问题。

钦定有 \(n\) 个人,一年 \(m=365\) 天。

那么 \(n\) 个人中没有任意两人生日相同的概率为

\[P=\prod_{i=1}^{n}\frac{m-i+1}{m} \]

那么反之存在二人生日相同即为 \(1-P\)。

\[\because 1+x\le e^x \]

\[\therefore P\le \prod_{i=1}^{n}e^{-\frac{i-1}{m}}=e^{-\frac{n(n-1)}{2m}} \]

而著名的悖论在于带入 \(n=23\) 即有 \(P\le 50\%\)。由于反直觉被认为是悖论。

事实上在 \(n=\sqrt{\frac{m}{\ln 2}}\) 左右时有 \(P=50\%\)。

考虑一个随机序列 \(X\) 由 \(f(x)=x^2+c\pmod n\) 生成。\(c\) 随机。

那么这个序列 \(X\) 在出现 \(x_i=x_j,i<j\) 时,\(X\) 就从 \(i\) 开始陷入循环。

即如上图所示,因其形像 \(\rho\) 而成为 \(\text{rho}\)。

那么这样的“伪随机”序列 \(X\) 产生环的期望其上述的生日悖论。

设 \(m\) 为 \(n\) 的最小非平凡因子。显然 \(m\le \sqrt n\),再记 \(y_i=x_i\pmod m\)。

\[\begin{aligned}\therefore y_{i+1}&=x_{i+1}\pmod m \\ & = x_i^2+c\pmod m\\&=(x_i\bmod m)^2+c\pmod m\\&=y_i^2+c\pmod m\end{aligned} \]

那么对于新的序列 \(Y\),若存在 \(i,j\) 使 \(x_i\neq x_j\) 且 \(y_i=y_j\),即 \(m\mid |x_i-x_j|,n\nmid |x_i-x_j|\).

那么令 \(g=\gcd(|x_i-x_j|,n)\),\(g\) 必然是 \(n\) 的一个非平凡因子。

期望枚举 \(O(\sqrt m)\) 次来获得 \(g\)。而 \(m\le \sqrt n\),故期望 \(O(n^{\frac{1}{4}})\)。

考虑优化。

  1. \(\text{Floyd}\) 判环

即通过双指针 \(i,j\),其中 \(i\) 的速度是 \(j\) 的两倍,以此去遍历环,那么 \(i,j\) 相遇时是环长整数倍。当然还是检查 \(g=\gcd(|x_i-x_j|,n)\)。复杂度 \(O(\sqrt[4] n\log n)\)。这里不做赘述。

  1. 倍增优化

多次求 \(\gcd\) 是时间复杂度的瓶颈,考虑如何优化。

每次将 \(|x_i-x_j|\) 相乘,若对于一对 \(x_I,x_J\),有 \(g\) 为 \(m\) 的非平凡因子,那么设 \(S=\prod|x_i-x_j|\),必然有 \(g'=\gcd(S,n)\) 亦为 \(n\) 的非平凡因子。

那么考虑累计到一定样本再进行 \(\gcd\)。考虑将阈值设为倍增,每次判断 \(g'<n\) 即可。

6. 反素数

素数是因子只有两个的数,反素数就是因子最多的数而不是emirp,并且因子个数相同的时候值最小。显然反素数是相对于一个集合的。

考虑对于一个反素数 \(n=\prod\limits_{i=1}^m p_i^{k_i}\),即有 \(\prod\limits_{i=1}^m(k_i+1)\) 取 \(\max\)。

考虑在给定范围内如何求反素数。

显然直接分解质因数无法接受。考虑反素数的性质。

  1. 反素数是从 \(2\) 开始的连续素数的幂次形式乘积。

显然。所以考虑 \(\min m\) 使 \(\prod\limits_{i=1}^{m+1}>n\),我们只需枚举前 \(m\) 个素数。

  1. 数值小的素数的幂次大于等于数值大的素数,即 \(k_1\ge k_2\ge \cdots \ge k_m\)。

还是显然。若有 \(k_i<k_j,i<j\) 则将 \(k_j-k_i\) 移至 \(p_i\) 幂次上更优。那么最坏枚举幂次枚举至 INT_MAX 差不多 \(64\) 即可。

整个过程就容易用搜索实现。

\(\text{CF27E}\)。模板题。

inline void dfs(int x,int k,int m,int dep){
	if(dep>n||x<=0ll||x>=ans||k>16)return;
	if(dep==n){
		ans=x;
		return;
	}
	x*=p[k];
	for(int i=1;i<=m;i++,x*=p[k])dfs(x,k+1,i,dep*(i+1));
	return;
}

二. \(\text {gcd}\) 相关

1. 求 \(\gcd\)

显然通过欧几里得/辗转相除容易在 \(O(\log n)\) 时间内递归求出 \(\gcd\)。

inline int gcd(int x,int y){
	if(!y)return x;
	return gcd(y,x%y);
}

考虑一个问题:求一组可行解 \((x,y)\) 满足 \(ax+by=\gcd(a,b)\)

设 \(ax_1+by_1=\gcd(a,b)\),\(bx_2+(a\bmod b)y_2=\gcd(b,a\bmod b)=\gcd(a,b)\)。

\[\therefore ax_1+by_1=bx_2+(a\bmod b)y_2=bx_2+(a-b\left\lfloor \frac{a}{b}\right\rfloor )y_2 \]

故 \(x_1=y_2,y_1=x_2-\left\lfloor \frac{a}{b}\right\rfloor y_2\)

那么剩余的按照普通的欧几里得递归做就行。

inline int exgcd(int a,int b,int &x,int &y){
	if(!b){
		x=1,y=0;
		return a;
	}
	int res=exgcd(b,a%b,x,y),X=x;
	x=y,y=X-(a/b)*y;
	return res;
}

2. 裴蜀定理

\(\forall a,b\in \mathbb Z(a\ or\ b\neq 0),\exists x,y\in\mathbb Z,ax+by=\gcd(a,b)\)。

证明:

设 \(g=\gcd(a,b),s=\min(ax+by)\in \mathbb N_+,t=\left\lfloor\frac{a}{s}\right\rfloor\),显然 \(\forall x,y\in \mathbb Z\) 有 \(g|ax+by\)。

\[\therefore a\bmod s=a-t(ax+by)=a(1-xt)+b(-yt) \]

那么 \(a\bmod s\) 是 \(a,b\) 的线性组合。同时有 \(0\le a\bmod s<s\)。再由 \(s\) 定义易知 \(a\bmod s=0\)。同理亦有 \(s|b\)。故 \(s\) 为 \(a,b\) 公约数。故 \(g\ge s\)。

又因为 \(g|a,g|b\) 且 \(s\) 为 \(a,b\) 线性组合。显然 \(g|s\)。那么即得 \(g=s\)。

裴蜀定理的一个推论:\(a,b\) 互质的充要条件是存在 \(x,y\in \mathbb Z\) 使 \(ax+by=1\)。此不做赘述。

那么这可看做是上述 exgcd 的一个补充。

3. 类欧几里得

虽然我并不知道这放在这个专题是否合适

标签:right,frac,数论,sum,杂谈,笔记,int,le,omega
From: https://www.cnblogs.com/trsins/p/17970748

相关文章

  • 【学习笔记】数论函数与莫比乌斯反演
    一.数论函数基础数论函数:满足值域为整数的函数。本文下述的数若无特殊说明均为整数。若无特殊说明则钦定\(\displaystylen=\prod_{i=1}^kp_i^{e_i},p_i\in\mathbb{P}\)。\(\mathbb{P}\)表示质数集合,\(p_i\)互不相同。介绍几个常见的数论函数:\(I(n)\):恒等函数,无论\(n\)......
  • 【学习笔记】Segment Tree Beats/吉司机线段树
    一.区间最值操作本文对吉如一老师在\(2016\)年国家集训队论文中的线段树处理历史区间最值的问题的一些杂谈。区间最值笼统地指求区间的最值以及区间所有数对\(x\)取最值(即令\(a_i=\max/\min(a_i,x)\))这一类的查询与修改操作。HDU5306GorgeousSequence支持对区间......
  • 多项式计数杂谈
    多项式计数杂谈-command_block的博客-洛谷博客command_block的博客导航切换首页文章command_block的博客多项式计数杂谈postedon2020-02-1118:16:01|under算法|Ox00.前面的话&前置芝士本文Markd......
  • 学习笔记6
    Scala匿名函数(函数字面量)Scala中的匿名函数也叫做函数字面量,既可以作为函数的参数使用,也可以将其赋值给一个变量,在匿名函数的定义中“=>”可理解为一个转换器,它使用右侧的算法,将左侧的输入数据转换为新的输出数据,使用匿名函数后,我们的代码变得更简洁了。valtest=(x:Int)=>......
  • Print linked list using recursion【1月17日学习笔记】
    点击查看代码//Printlinkedlistusingrecursion#include<iostream>usingnamespacestd;structnode{ intdata; node*next;};voidprint(node*p){ if(p==NULL)return;//递归中止条件 cout<<p->data<<""; print(p->next)......
  • Reverse a linked list【1月17日学习笔记·】
    点击查看代码//Reverssealinkedlist#include<iostream>usingnamespacestd;structnode{ intdata; node*next;};node*A;voidreverse(){ node*next;//用于保存下一个·节点地址以便索引 node*current=A;//当前索引 node*prev=NULL;//保存上一个节点......
  • Avalonia 11 学习笔记
    Avalonia学习之样式Avalonia学习之样式的选择器和伪类Avalonia学习之资源使用Avalonia学习之绑定Avalonia学习之属性Avalonia学习之自定义控件Avalonia实现一条虚线Avalonia使用d:DataContext实现设计时预览Avalonia实现滑动加载Avalonia通过ef操作sqlite......
  • Delete d node at nth position【1月17日学习笔记】
    点击查看代码//Deletednodeatnthposition#include<iostream>usingnamespacestd;structnode{ intdata; node*next;};node*A;voidinsert(intx){ node*temp=newnode; temp->data=x; temp->next=NULL; if(A==NULL){ A=temp;......
  • 【Tools】Eclipse MemoryAnalyzer(MAT)工具使用笔记
    目录一、前言1.1简介1.2下载安装二、使用2.1Histogram(直方图)2.2DominatorTree(支配树)2.3TopConsumers2.4DuplicateClasses(重复类)2.5Suspects(疑似泄露点)三、问题总结3.1分析源码3.2解决办法一、前言1.1简介EclipseMemoryAnalyzer是一个快速且功能丰富的Java堆分......
  • Inserting a node at nth position【1月17日学习笔记】
    点击查看代码//Insertinganodeatnthposition#include<iostream>usingnamespacestd;structnode{intdata;node*next;};node*A;//全局头指针voidinsert(intx,intn){node*temp=newnode;//temp是局部变量,在stack区,每次调用更新temp-......