简单数论知识梳理(省选复习)

(noip数论算法汇总)

①扩展欧几里得

int ex_gcd(int a,int b,int &x,int &y)
{
	if(!b)
	{
		x=1,y=0;
		return a;
	}
	int g=ex_gcd(b,a%b,x,y);
	int t=x;x=y,y=t-a/b*y;
	return g;
}
应用及要点:

one :   求形如ax+by=gcd(a,b)的一组解(x,y)  (有解情况当且仅当ab互质)

    要注意的是,已知一组解(x0,y0),则其他所有解都可以表示成(x0+k*b,y0-k*a)

    想像成直线就可以理解了

two:    求逆元,ax≡1 mod(p) 可以转化为 ax-py=1


另:

辗转相除和辗转相减法两个定理:

辗转相减法:gcd(a,b)=gcd(a-b,b)

辗转相除法:gcd(a,b)=gcd(a%b,b)

②分解质因数

O(sqrt(n))太无脑了无视掉

O(n)预处理和O(log(a))分解:

线性筛法预处理 dy[i] 表示i的最小质因子在prime数组中的编号

分解时每次除以最小质因子即可做到log的分解质因数

代码:

void init()
{
	for(int i=2;i<=n;i++)
	{
		if(!vis[i])prime[++cnt]=i;
		for(int j=1;j<=cnt;j++)
		{
			long long tmp=prime[j]*i;
			if(tmp>=N)break;
			vis[tmp]=1,dy[tmp]=j;
			if(tmp%prime[j]==0)break;
		}
	}
}
int num[N];
void work(int x)
{
	while(x!=1)
	{
		num[dy[x]]++;
		x/=prime[dy[x]];
	}
}

③逆元:

常用的有三种,扩展欧几里得上面提到了,下面只写费马小定理和线性递推求逆元

费马小定理:a^(p-2)是a在膜p意义下的逆元,即a^(p-1)%p=1

ll qm(ll a,ll b)
{
	ll ret=0,t=a;
	while(b)
	{
		if(b&1)ret=ret*t%mod;
		t=t*t%mod;b>>=1;
	}return ret;
}
ll inv(ll x){return qm(x,mod-2); }
线性递推逆元:  inv[1]=1,inv[i]=inv[p%i]*(p-p/i)%p

让我来认真的证明一次上式.....(noip前真的是差到连这玩意都不会证.......)

设 t=p/i,k=p%i

则 p=t*i+k

即 (t*i+k)≡0(mod p)

=>  -t*i≡k(mod p)

两边同时除以i*k

=> -t*inv[k]≡inv[i](mod p)

故inv[i]=-t*inv[k](mod p)

转成正数:inv[i]=(-t+p)*inv[k](mod p)

所以 inv[i]=(p-p/i)*inv[p%i](mod p)

可以愉快的线性推逆元啦23333

int inv[N];
void init()
{
	inv[1]=1;
	for(int i=2;i<mod;i++)
		inv[i]=(mod-mod/i)*inv[mod%i]%mod;
}
④欧拉函数:

 线性筛求欧拉函数前面一篇博客里已经提到过,在此不提

欧拉函数的意义:

phi[n]=小于n的数中与n互质的数的个数

定义式:

phi[n]=n*(1-1/p1)*(1-1/p2)*(1-1/p3)....(1-1/pk)

这很简单就不放代码了。

应用:

one :上一个求逆元中还有一种方法没有说到就是欧拉函数。

   有欧拉定理:a^φ(n)  ≡ 1 mod n 

two : 按定义,求小于n且与n互质的数的个数(2333)

three:求n以内与n互质的数的和

    有公式:sum(n)=phi(n)*n/2; (sum(n)为小于n的所有与n互质的数的和)


⑤一些实用的定理:

约定:

唯一分解式形为n=p1^a1*p2^a2*p3^a3*…*pk^ak

约数个数定理: n的约数个数=(a1+1)*(a2+1)*(a3+1)....(ak+1)

约数和定理:     n的约数和=(p1^0+p1^1+p1^2...p1^a1)*(p2^0+p2^1+p2^2....p2^a2)...(pk^0+pk^1...pk^ak)

基础的数论知识差不多就是这些了,后面几篇博客会对几个重要的数论知识点进行详解或较多例题复习

⑥等比数列求和的分治算法:

定理:

对于Sn=a^1+a^2+...+a^n

当n==0时Sn=1;n==1时Sn=a

当n为偶数时:

Sn=S(n/2)*(a^(n/2)+1)

当n为奇数时:

Sn=S(n/2)*(a^(n/2+1)+1)+(a^(n/2)+1)

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值