数论小结

 

     一. 唯一分解定理

           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 
#include 
#include 
#include

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(aa-b) b=a-b;
    ll ans=1,ca=1,cb=1;
    for(int i=0;i>a>>b>>m){
        cout<

扩展欧几里得实现: 

#include 
#include 
#include 
#include

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(aa-b) b=a-b;
    ll ans=1,ca=1,cb=1;
    for(int i=0;i>n;
    while(n--){
        cin>>a>>b>>m;
        cout<

续~矩阵快速幂相关问题

  1.求逆元博客:https://blog.csdn.net/guhaiteng/article/details/52123385

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

你可能感兴趣的:(算法)