数论(凑标题字数)

1、唯一分解定理
2、阶乘质因子分解
3、欧几里得、扩展欧几里得
4、逆元
5、卡特兰数通项公式

一、唯一分解定理
任何一个大于1的整数n都可以分解成若干个素因数的连乘积,如果不计各个素因数的顺序,那么这种分解是唯一的。
即n=p1a1p2a2…pkak
(1)一个大于1的正整数N,如果他的标准分解式为N=P1a1P2a2…Pnan,那么它的正因数个数之和为
σ(N)=(1+a1)(1+a2)…(1+an)。
(2)它的全体正因数之和为
σ1(N)=(1+p1+p12+…+p1a1)(1+p2+p22+…+p2a2)…(1+pn+pn2+…+pnan)。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const int MAXN=100001;
int p[MAXN],c[MAXN];//p数组表示该因子,c数组表示在p中对应因子的次数 
int n,sum;
int main()
{
	while(scanf("%d",&n)!=EOF){
		memset(c,0,sizeof(c));
		sum=0;
		int m=sqrt(n);
		for(int i=2;i<=m;i++){
			if(n%i==0){
				p[++sum]=i;
				while(n%i==0){
					n/=i;
					c[sum]++;
				}
			}
		}
		if(n>1){
			p[++sum]=n;
			c[sum]++;
		}
		for(int i=1;i<=sum;i++)
			printf("%d %d\n",p[i],c[i]);
	}
	return 0;
}

二、阶乘质因子分解
贡献为2的:[n/2]+[n/22]+[n/23]+…
贡献为3的:[n/3]+[n/32]+[n/33]+…
贡献为5的:[n/5]+[n/52]+[n/53]+…

#include<iostream>
using namespace std;
const int MAXN=1e8+10;
int n,t,sum;
int prime[MAXN],visit[MAXN],cnt[MAXN];
//素数筛
int set(int n){
    for(int i=2;i<=n;i++){
        if(!visit[i]){
            prime[++sum]=i;
        }
        for(int j=1;j<=sum&&i*prime[j]<=n;j++){
            visit[i*prime[j]]=1;
            if(!i%prime[j]){
                break;
            }
        }
    }
}
int main()
{
	scanf("%d",&n);
	set(n);
	//质因子分解
	for(int i=1;i<=sum;i++){
		t=n;
		while(t)
		{
			cnt[i]+=t/prime[i];
			t/=prime[i];
		}
	}
	for(int i=1;i<=sum;i++)
		cout<<prime[i]<<" "<<cnt[i]<<endl;
	cout<<endl;
    return 0;
}

三、欧几里得+扩展欧几里得
(1)欧几里得算法
欧几里德有个定理: gcd(a, b) = gcd(b , a%b) ,这样我们就可以在几乎是 log 的时间复杂度里求解出来 a 和 b 的最大公约数了,这就是欧几里德算法, C++ 语言描述如下:

//辗转相除求gcd
int gcd(int a,int b)
{
	if(b==0) return a;
	else return gcd(b,a%b);
}

(2)扩展欧几里得算法
现在我们知道了 a 和 b 的最大公约数是 gcd ,那我们能够找到这样的 x 和 y ,使得: ax + by = gcd 这是一个不定方程,有多解是一定的,但是只要我们找到一组特殊的解 x0 和 y0 那么,我们就可以用 x0 和 y0 表示出整个不定方程的通解:
ax+by=c①
ax0+by0=c②
①-②联立解得a(x-x0)+b(y-y0)=0
即a(x-x0)=b(y0-y)
若a、b互质,那么x-x0一定含因子b,y0-y必含因子a
即x-x0=kb,y0-y=ka(k∈Z)
所以通解为x=x0+bk,y=y0-ak
若c=gcd(a,b),求特解x 和 y 只需要在欧几里德算法的基础上加点改动,欧几里德算法停止的状态是: a= gcd , b = 0 。这时候,只要 a = gcd 的系数是 1 ,那么只要 b 的系数是 0,我们就会有: a1 + b0 = gcd
由欧几里得定理gcd(a,b)=gcd(b,a%b)
ax1+by1=bx2+(a%b)y2
ax1+by1=bx2+[a-(a/b)b]y2
ax1+by1=bx2+ay2-b(a/b)y2
ax1+by1=ay2+b[x2-(a/b)y2]
所以x1=y2,y1=x2-(a/b)y2,用递归求解,边界条件gcd(a,0)

int exgcd(int a,int b,int &x,int &y)
{
	if(b==0)
	{
		x=1;
		b=0;
		return a;
	}
	int ans=exgcd(b,a%b,x,y);
	int tmp=x;
	x=y;
	y=tmp-a/b*y;
	return ans;
}

四、逆元
条件:若a, p 互质,a有关于p的逆元。
a的逆元表示为inv(a),ainv(a) ≡ 1 mod p
求法①费马小定理
a^(p-1) ≡1 (mod p)
两边同除以a
a^(p-2) ≡1/a (mod p)
即inv(a)≡a^(p-2) (mod p)
求法②欧几里得算法
a
x + b*y = 1
如果a,b互质,有解x1 y1
x1就是a关于b的逆元
y1就是b关于a的逆元

证明:
			两边同时对b取模
		    a*x % b= 1 %b
	        即a*x ≡ 1 (mod b)

五、卡特兰数通项公式
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值