费马小定理

假如p是质数,且gcd(a,p)=1,那么 ,即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。

和同余定理可以一起用在当指数很大的时候。比如要整体MOD 1e9+7,可以对指数MOD 1e9+6,然后再将快速幂得到的MOD 1e9+7。参见nbuoj2700。

逆元一般用扩展欧几里得算法来求得,如果img为素数,那么还可以根据费马小定理得到逆元为img

逆元

如果ax≡1 (mod p),且gcd(a,p)=1(a与p互质),则称a关于模p的乘法逆元为x。
a和p互质,a才有关于p的逆元。b的逆元,我们用inv(b)来表示,那么(a/b)%p=(a×inv(b))%p=(a%p×inv(b)%p)%p,这样就把除法,完全转换为乘法了 。
逆元的求法:
方法一:用费马小定理。
在p是素数的情况下,x^(p−2)即为x关于p的逆元。

long long PowerMod(int a,int b,int c)
{
    long long ans=1;
    long long k;
    k=a;
    k=k%c;
    while(b>0)
    {
        if(b%2==1)
        ans=(ans*k)%c;
        b=b/2;
        k=(k*k)%c;
    }
    return ans;
}
long long Fermat(int x,int p)
{
    return PowerMod(x,p-2,p);
}

方法二:用扩展欧几里得算法。
因为ax≡1(mod p),所以ax-py=1,应用一下扩展欧几里得算法即可。

void extgcd(int a,int b,int d,int &x,int &y)   //a,b都为正整数
{
    if(b==0){d=a;x=1;y=0;}
    else{extgcd(b,a%b,d,y,x);y=y-x*(a/b);}
}
int inverse(int a,int p)
{
    int d,x,y;
    extgcd(a,p,d,x,y);
    return d==1?(x%p+p)%p:-1; //x是应为正整数,即需要若x为负整数,则需要将之化正,即与负数取模同理,将x加上p,直至x>0为止,所得的数即为最小的乘法逆元。
}
int main()
{
    int a,p;
    scanf("%d%d",&a,&p);
    inverse(a,p);
    return 0;
}

方法三:线性时间求所有逆元。

void mutl(int mod)
{
	int inv[M];inv[1]=1;//边界条件 
	for (int i=2;i<=M;i++) 
		inv[i]=((-(mod/i)*inv[mod%i])%mod+mod)%mod; //防止出现负数 
	return ; 
}

这个方法不限于求单个逆元,比前两个好,它可以在O(n)的复杂度内算出n个数的逆元,递归就是上面的写法,加一个记忆性递归,就可以了,递推这么写:

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

阶乘的逆元

void init()
{
    fac[0]=fac[1]=1;
    for(int i=2;i<=MAXN;i++)
        fac[i]=fac[i-1]*i%MOD;
    inv[MAXN]=PowerMod(fac[MAXN],MOD-2,MOD);
    for(int i=MAXN-1;i>=0;i--)
        inv[i]=inv[i+1]*(i+1)%MOD;
}
调和级数

1+1/2+1/3+……+1/n=ln(n)。

唯一分解定理

任何一个大于1的自然数N,有标准分解式

它的正因子个数为

正因子数之和为

费马大定理

当整数n>2时,关于x,y,z的方程没有正整数解。

勾股数的构造

,已知a,构造出b和c。

若a=1或a=2,无解;

若a为奇数,

若a为偶数,

过程:

因为所以

时,

时,

解方程即可。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

组合数取模 Previous
高精度和低精度的乘除法&&大数取模 Next