[探究] OI中各种初级数论算法相关

嗯,写这个是因为我太弱了ORZ.

#1  Linear  Sieve  Method  of  Prime线性筛素数

嗯,其实对于这个而言,无非就是一个break不易理解而已。

if(! (i % prime[j])) break ;

那么我们先来分析线性筛的复杂度,嗯,很显然因为是O(n)才称其为线性筛法。所以也就是说,对于每个合数,我们只让它被筛去一次。那么线性筛是如何保证的呢?答:每个合数都会被自己最小的质因子筛掉

下面让我们来分析合理性,说是证明其实就是逻辑演绎

证明一:在线性筛法中,每个合数都会被自己最小的质因子筛掉。

我们令N为一个合数,且他的标准分解式为

N=p1k1p2k2p3k3...ptkt

不妨令

p1<p2<p3...<pt

考虑当用 p1 筛除时,令

N=Np1

那么会因为pi会第一次被使用而使得N被成功筛掉(k1的值无关紧要,即无论N是否是i的倍数,只会在这之后跳出)。但是我们考虑,如果用ps(s1)筛除的话,那么若令

i=Nps

则一定有

p1|i

从而会使得在prime[j]刚枚举到p1还未枚举到ps时跳出,使其不能被筛掉。

所以得出结论,在线性筛法中,每个合数都会且仅会被自己最小的质因子筛掉。

证明二:线筛中,每个合数当前不被筛的原因是因为它要被放到之后去筛。

对于N的两个因子pr<ps,他们会分别在i=Npri=Nps时筛掉,因为pr<ps,所以会有i>i。结合证明一,由于N一定会被最小的pi筛除,所以可以得出此时的i一定为最大,所以必须等到所枚举的i更大时,N才会被筛除。

#2  Sieve  Method  of  Euler欧拉筛

首先我们需要有一个前置技能:φ(x)×ϕ(y)=φ(x×y)<=>(x,y)=1

那么类比线性筛而言,我们可以发现,对于一个素数p而言,φ(p)=p1,那么因为凡是素数必然在合数之前被筛到,所以我们可以考虑以此为基进行欧拉筛。那么,由于若W=a×bgcd(a,b)=1,就会有φ(W)=φ(a)×φ(b),所以有

else 
phi[i*prime[j]]=phi[i]*phi[prime[j]];

那么对于另一种情况w=i×j,i  mod  j=0而言,我们考虑有i=jn1×x且其中gcd(jn,x)=1

那么此时就会有φ(w)=φ(jn)×φ(x)

而因为事实上$$\varphi(j{n})=jn-j^{n-1}$$

故$$\varphi(x) \times (j{n-1}-j)=\varphi(x) \times \varphi(j^{n-1})= \varphi(i)$$

所以会有$$\varphi(w)=\varphi(x) \times j\times(j{n-1}-j)$$

φ(w)=φ(i)×j

所以:

if(i%prime[j]==0)
{
	phi[i*prime[j]]=prime[j]*phi[i];
	break;
}

#3  Linear  Recursion  of  Inverse  Element线性推逆元

首先来思考逆元是个什么东西:

a×x1(mod  b) ,且 ab 互质,那么我们就能定义: xamod  b的逆元,记为 a1

再来思考逆元有个什么用处:

对于 ab(mod  p) ,我们就可以求出 bmod  p下的逆元,然后乘上 a,再mod  p,即可得出结果。

好的那么我们来看一下这玩意儿怎么线性推QAQ:

首先我们令p=k×i+r,0<r<i

然后显然的是

k×i+r0(mod  p)

两边同时乘上i1r1

k×r1+i10(mod  p)

移个小项

i1k×r1(mod  p)

换个元

i1pi×(p  mod  i)1(mod  p)

于是就华丽丽地结束了qwq

inv[1]=1;
for(i = 2; i <= n; i ++)
{
	inv[i] = - (p / i) * inv[p % i] ;
	inv[i] = (inv[i] % p + p ) % p ;
}

#4  Eulers  Formula  欧拉公式

欧拉公式是世界上最美妙的公式 ——苏格拉底【雾

首先让我们来看看这个公式的样子:eix=cosx+isinx其中i复数单位:i=1
那么它美妙在哪里呢?我们会发现它联系了最重要的无理数之一——e、复数域i和基本初等函数sincos这些东西,所以被冠以“最优美、最伟大桥梁”“数学上的天桥”等美称。

但是这远远不是最美妙的,最美妙的是,当你取x=π时,会有eπi+1=0还有什么比这更美妙吗?我们通过这个公式,成功地将两个最重要的超越数πe、复数中的“地基”i、自然数中最美妙的01,在这一个公式中被我们尽收眼底qwq

那么,现在有没有引起你的兴趣?如果有,我们来看证明吧:

首先我们需要前置技能——泰勒展开

泰勒公式是将一个在x=x0处具有n阶导数的函数f(x)利用关于(xx0)n次多项式来逼近函数的方法。

若函数f(x)在包含x0的某个闭区间[a,b]上具有n阶导数,且在开区间(a,b)上具有(n+1)阶导数,则对闭区间[a,b]上任意一点x,成立下式:

——baidu百科

这就是泰勒展开式,正确性证明暂时不会,右边的那个幂级数又叫做泰勒级数,我们可以理解为我们把某些特定的函数展开成了幂级数的形式。

ps:如果无法理解的话……看高数去吧!【下册即可

好啦,扯这么多其实就是说,我们右边的sincos都是可以被展开……换种方式表示的qwq.

那么他们展开之后大约是这样子:$$\forall x, sinx = \sum\limits_{n = 0}{\infty}{\frac{(-1)n}{2n + 1}!x^{2n + 1}}\forall x, cosx = \sum\limits_{n=0}{\infty}{\frac{(-1)n}{2n}!x^{2n}}$$

等式左边$$e^x = \sum\limits_{n=0}{\infty}{\frac{1}{n!}}$i$i1 = i,i^2 = -1, i^3 = -i, i^4 = 1.....$$那我们的左边可以得到

而因为对于sincos的泰勒级数我们可以写成这样:


所以有eix=cosx+isinx

证毕。

ps:如果你细心+聪明的话,会看到无理数e的递推公式哦!

# 5  Numbertheory  Partitioning数论分块

好的,数论分块也叫做整除分块,是数学问题中一个优化时间复杂度的技巧,通常解决的是一个子问题——没错,是用来解决一个很常见的子问题,或者与其相似的子问题。

233也就是说大部分情况他就只有一个用处:

i=1nni并要求复杂度Θ(n)

这个问题优化的方向是缩小规模——之所以可以缩小规模,是因为我们发现原来当n=7 的时候,i=5i=6以及i=7的值都一样,于是我们思考可以分块乱搞一下。那么分块怎么分块呢?我们可以有以下这个程序:

for(l = 1 ; l <= N ; l = r + 1){
        r = N / (N / l) ;
        Ans += (r - l + 1) * (N / l) ;
    }

看起来……比较明朗的是这确实是一个分块,并且跟我们上文提及的指导思想十分的相似……

However你还是不知道他到底是怎么分的块TAT

那么精彩的证明就要开始了惹~

Task1先证一下“指导思想”

这个emmm应该是复杂度的证明233

命题:nN+,in=>cnt(ni)<2n其中cnt(f(x))表示整值多项式f(x)的值域大小。

(人话版本:我们接下来要证明ni 最多有2n1种取值,也就是证我们最多要进行的运算次数是n级别的)

以下是证明:

我们分成两种情况来考虑:ini>n

我们先思考简单点的,当i>n时,此时对于全部的ni最大不会超过n 1,所以其取值不会超过n的级别。

那么对于in的情况,我们思考去证明另一件事——证明nini+1

那么我们此处不妨用反证法,假设ni=ni+1.我们不妨令n=ik+q (0q<i) ,则我们可以得到ink 继而得到k>q

那么根据假设,我们很显然会有n=(i+1)k+q,(0q<i+1)

也就会有下面这个等式n=ik+k+q=ik+q+(k+qq)=n+(k+qq) 但是因为我们已经证完了的k>q 所以等式左边一定不会等于等式右边……所以出现矛盾。

那么我们就通过反证法证明了结论nini+1,从而有几个不同的in就会有几个不同的取值。

所以得出结论,cnt(ni)<2n

Q.E.D.

好的,刚才的证明和正确性没啥关系……好吧跟时间复杂度的正确性有关系……那就跟正确性有关系好了……我在说些什么奇怪的东西……2333333333333333333

接下来证明那一句玄学的

r = N / (N / l) ;

Task2再证一下正确性

首先我们意会一下……我们所做的工作,就是要找出极小的l和极大的r,对于给定的ω有$ c \in [l,r]\lfloor \frac{n}{c} \rfloor = \omega$ 。那么根据我们上一个证明中的下半部分我们可以知道,这就是一个极大块,并且下一个极大块是从r+1开始的,因为极大块必然满足nrnr+1.

那么我们要找的就是每个极大块的右断点r

命题:如果已知n,pN+,pn,那么满足np=ni的最大的i满足i=nnp

(其实这个玩意儿是可以意会出来的233)

以下是证明:

我们不妨继续分类讨论:

pn时:

不妨继续设n=kp+q,(0q<p)

那么我们可以得到比较显然的结论是nnp=nk且因为当pn时,np互不相同,所以imaxp=p,我们只需要证明 p=nk 而这个结论是显然的。因为q<pk ,所以得证p=nk

p>n 时:

直接证似乎不是很容易,那么我们思考一个转化。因为对于一个p我们要证明的imaxp有两个性质:nimaxp=np=k并且nimaxp+1np

那么由于nnp=nk 所以我们不妨把要求的imaxp换成nk 并说明nnk=np=k并且 nnk+1np

而此时由于k<n, 所以我们发现原来就是当pn时的结论。于是我们就无比迅速地得到了nnk=k并且由Task1中的结论推出了nnk+1k

于是乎:

Q.E.D.

那么我们就证完了!想不到这个这么显然的结论这么好背的结论居然是迄今为止这篇博客中我花费心血最多的233……

嗯,我被自己帅到了嘿嘿~

#6 Something About Ackerman Function 阿克曼函数相关

不知道为什么就开始颓这个函数……

感觉很牛13的样子……

以下大部分内容来自Wiki(主要是智障楼主找不到更好的材料了)

首先我们先解释一下箭头表示法这个东西(一时编不出什么更好的名字)

我们用表示“迭代相乘”,譬如说24表示24,而34则表示34

同时,我们用↑↑表示“迭代取幂”,它的意思是a↑↑b=aaa ,等式右边一共有ba

同时,我们用↑↑↑表示“迭代迭代取幂”……

好吧,其实这玩意儿是递归定义的,借鉴的wiki的我承认233……

anb={ab,if n = 11,if b = 0an1(an(b1)),otherwise

那么这东西用处是啥呢?其实我们如果用它来表示大数的话,是比科学计数法更容易的,比如a19260817就看起来很繁琐是吧233

那么接下来,我们来介绍真正地Ackerman函数。很巧的是,这东西也是递归定义的:

A(m,n)={n+1,if m = 0A(m1,1),if m > 0 & n = 0A(m1,A(m,n1)),otherwise

并且,这东西十分的,当m4 & n>2的时候就已经十分不可算了,因为事实上A(4,3)=2655363,不知道会不会爆python 23333

posted @   皎月半洒花  阅读(2650)  评论(5编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
点击右上角即可分享
微信分享提示
哥伦布
05:09发布
哥伦布
05:09发布
7°
多云
西北风
2级
空气质量
相对湿度
67%
今天
小雨
7°/21°
周五
多云
11°/22°
周六
大雨
16°/24°