数论小结

本文总结了数论的一些核心概念,包括唯一分解定理、除法取模的技巧、逆元的求法,以及如何利用扩展欧几里得算法解线性同余方程。还介绍了求解n!中因子个数的方法、欧拉函数的应用和卢卡斯定理在组合计算中的作用。通过实例解析,深入理解数论在实际问题中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

     一. 唯一分解定理

           A=p1^a * p2^b * p3^c(其中p1,p2,p3为A的质因子)

            1. A的因子数:num=(a+1)*(b+1) * (c+1)*...;

            2 . A的因子和:

                sum(c)=p1^0 + p1^1 + ... p1^a+;

                sum(d)=p2^0 + p2^1 + ...+ p2^b;

                sum(e)=p3^0 + p3^1 +...+ p3^c;

                     ..............

                sum=sum(b) * sum(d) * sum(e)*...;

     二. 除法取模:

       1.(x/d)%k =x%(d*k)/d (x/d!=0)(等比数列求和中快速幂模)

         例:http://acm.hdu.edu.cn/showproblem.php?pid=4990

       2. (x/d)%k=(x* d1) %k   (d1为d的逆元)

      三.逆元求法:

       逆元定义:ax=1 (mod m)---->ax+my=1 —>exgcd(a,m)

       1. 扩展欧几里得算法:

          ax+by=gcd(a,b)=1, x为a的逆元 y为b的逆元;   

int exgcd(int a,int b,int &x,int &y)
{
	int d=a;
	if(d==0)
	{
		x=1;
		y=0;
	}
	else
	{
		d=exgcd(b,a%b,y,x);
		y-=a/b*x;
	}
	return d;
 } 
 //求ax=1 (mod m) 
int get_number(int a,int mod)
{
	int x,y;
	int temp=exgcd(a,mod,x,y);//另ax+by=1 中的a=a b=mod;;
	if(temp!=1) 
	{
		printf("-1\n");//不存在 
	}
	else printf("%d\n",x);//a的逆元为x; 
}

      2.费马小定理求逆元:

        对任意的P,A互质,都有A的(P-1)次方取模与P等于1,公式表示为:

         A^p-1≡1(mod P)

         A*X≡1(mod p)   两式得出A的逆元X=A^p-2(快速幂计算)

         注:此时满足P,A互质(p为质数常用)

四:扩展欧几里得解线性同余方程

     ax=b (mod m)------>ax-my=b 令d=exgcd(a,m,x,y)

     则 x=x0 * b/d 为方程一解 mod=m/d (解集:x=x0*b/d+k*mod);

     非负最小解:x=(x%mod+mod)%mod(如果x==0 x+=mod);

 例:http://poj.org/problem?id=2115

另外:若方程为ax+by=c 时 同上

 例:http://poj.org/problem?id=1061

五:求n!中因子个数

      结合唯一分解定理 M=(e1+1)*(e2+1)*...*(en+1)

      以及公式  ei=[N/pi^1]+ [N/pi^2]+ …… + [N/pi^n] 其中pi为n以内的素数,ei当n!在

      分子为正 分母为负

例:http://poj.org/problem?id=2992

六:欧拉函数的实现:

void euler(int n)//求n的欧拉函数值 
{
	int ans=n,temp=n;
	for(int i=2;i*i<=temp;i++)
	{
		if(n%i==0)//i为素数 且是n的因子 
		{
			ans=ans-ans/i;
			while(n%i==0) n/=i; 
		}
	 } 
	 if(n>1) ans=ans-ans/n;
	 return ans;
}
//欧拉函数的筛选法
int phi[maxn+10];
void get_phi()
{
	for(int i=0;i<=maxn;i++) phi[i]=i;
	for(int i=2;i<=maxn;i++)
	{
		if(phi[i]==i)
		{
			for(int j=i;j<=maxn;j+=i)
			{
				phi[j]=phi[j]/i*(i-1);
			}
		}
	}
}

 七:卢卡斯定理

卢卡斯定理主要用来求组合 C(n,m) %p

费马小定理实现(p为素数):

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include<cstring>

using namespace std;

typedef long long ll;

ll mulit(ll a,ll b,ll m){
    ll ans=0;
    while(b){
        if(b&1) ans=(ans+a)%m;
        a=(a<<1)%m;
        b>>=1;
    }
    return ans;
}

ll quick_mod(ll a,ll b,ll m){
    ll ans=1;
    while(b){
        if(b&1){
            ans=mulit(ans,a,m);
        }
        a=mulit(a,a,m);
        b>>=1;
    }
    return ans;
}

ll comp(ll a,ll b,ll m){
    if(a<b) return 0;
    if(a==b) return 1;
    if(b>a-b) b=a-b;
    ll ans=1,ca=1,cb=1;
    for(int i=0;i<b;i++){
        ca=ca*(a-i)%m;
        cb=cb*(b-i)%m;
    }
    ans=ca*quick_mod(cb,m-2,m)%m;
    return ans;
}

ll lucas(ll a,ll b,ll m){
    ll ans=1;
    while(a&&b){
        ans=(ans*comp(a%m,b%m,m))%m;
        a/=m;
        b/=m;
    }
    return ans;
}

int main()
{
    ll a,b,m;
    while(cin>>a>>b>>m){
        cout<<lucas(a,b,m)<<endl;
    }
    return 0;
}

扩展欧几里得实现: 

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include<cstring>

using namespace std;

typedef long long ll;

ll exgcd(ll a,ll b,ll& x,ll& y){
    if(a%b==0){
        x=0,y=1;
        return b;
    }
    ll r,tx,ty;
    r=exgcd(b,a%b,tx,ty);
    x=ty;
    y=tx-a/b*ty;
}

ll comp(ll a,ll b,ll m){
    if(a<b) return 0;
    if(a==b) return 1;
    if(b>a-b) b=a-b;
    ll ans=1,ca=1,cb=1;
    for(int i=0;i<b;i++){
        ca=ca*(a-i)%m;
        cb=cb*(b-i)%m;
    }
    ll x,y;
    exgcd(cb,m,x,y);
    x=(x%m+m)%m;
    ans=ca*x%m;
    return ans;
}

ll lucas(ll a,ll b,ll m){
    ll ans=1;
    while(a&&b){
        ans=(ans*comp(a%m,b%m,m))%m;
        a/=m;
        b/=m;
    }
    return ans;
}

int main()
{
    ll a,b,m;
    int n;
    cin>>n;
    while(n--){
        cin>>a>>b>>m;
        cout<<lucas(a+b,b,m)<<endl;
    }
    return 0;
}

续~矩阵快速幂相关问题

  1.求逆元博客:https://blog.youkuaiyun.com/guhaiteng/article/details/52123385

  2.指数逆元https://blog.youkuaiyun.com/qq_35703773/article/details/78428127?readlog

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值