• 数论一点点总结


    数论基础

    最大公约数Gcd

    int gcd(int a, int b) //a大于b
    {
    	return a % b == 0 ? b : gcd(b, a % b);
    }
    

    最小公倍数Lcm

    int Lcm(int a,int b)
    {
    return a/gcd(a,b)*b;
    }
    

    费马小定理

    费马小定理(Fermat Theory)是数论中的一个重要定理,其内容为:假设p是质数(素数),且
    Gcd(a,p)=1,那么a^(p-1) ≡1(mod p)。即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。该定理是1636年皮埃尔·德·费马发现的。 费马小定理在ACM数论题中应用还是较多的。

    唯一分解定理

    算术基本定理,又称为正整数的唯一分解定理,即:每个大于1的自然数均可写为质数的积,而且这些素因子按大小排列之后,写法仅有一种方式。(素数的分解方法唯一)例题Pairs Forming LCM运用到唯一分解定理的好题。

    拓展的欧几里得算法

    扩展欧几里得算法(英语:Extended Euclidean algorithm)是欧几里得算法(又叫辗转相除法)的扩展。已知整数a、b,扩展欧几里得算法可以在求得a、b的最大公约数的同时,能找到整数x、y(其中一个很可能是负数),使它们满足贝祖等式ax + by = gcd(a, b).
    如果a是负数,可以把问题转化成|a|(-x)+by=gcd(|a|,b),然后令 x'=(-x)。
    通常谈到最大公约数时,我们都会提到一个非常基本的事实:给予二个整数a、b,必存在整数x、y使得ax + by = gcd(a,b)[1]。有两个数a,b,对它们进行辗转相除法,可得它们的最大公约数——这是周知的。然后,收集辗转相除法中产生的式子,倒回去,可以得到ax+by=gcd(a,b)的整数解。
    例如:求一对正整数(x,y),使得ax+by=gcd(a,b)。
    代码如下:

    void exgcd(int a,int b,int &d,int & x,int & y)
    {
    if(!b){
    d=a;x=1;y=0;
    }
    else {
    exgcd(b,a%b,d,y,x);
    y-=x*(a/b);
    }
    }
    

    提示:设a #,b,c为任意整数,如果方程ax+by=c的一组整数解为(x0,y0),则它的任意整数解可以写成(x0+kb',y0-ka'),其中a'=a/gcd(a,b),b'=b/gcd(a,b),k取任意整数。

    Eratosthenes筛法

    筛法的思路的忒简单:对于不超过n的每个非负整数p,删除2p,3p,4p....当处理完所以的数之后,剩下的就是素数了。vis[i]表示i以及被删除,代码如下复杂度O(nlogn)

    memset(vis,0,sizeof(vis));
    for(int i=2;i<=n;i++)
    for(int j=2*i;j<=n;j+=i)
    vis[j]=1;
    

    改进一点:p可以限定素数,如果是素数,则不进行第二重循环;内层循环也不必从i*2开始——它在i=2是以及被筛掉,代码如下:

    int m=sqrt(n+0.5);
    memset(vis,0,sizeof(vis));
    for(int i=2;i<=m;i++)
    if(!vis[i])
    for(int j=i*i;j<+n;j+=i)
    vis[j]=1;
    

    素数定理

    π(x)~x/ln(x)。
    其中 ln x 为 x 的自然对数。上式的意思是当 x 趋近无限,π(x)与x/ln x的比值趋近 1。但这不表示它们的数值随着 x 增大而接近。
    对正实数x,定义π(x)为素数计数函数,亦即不大于x的素数个数。

    逆元(inv)

    1.什么是逆元

    当求解公式:(a/b)%m 时,因b可能会过大,会出现爆精度的情况,所以需变除法为乘法:
    设c是b的逆元,则有bc≡1(mod m);
    则(a/b)%m = (a/b)
    1%m = (a/b)bc%m = ac(mod m);
    即a/b的模等于a
    b的逆元的模;
    逆元就是这样应用的

    2.求逆元的方法

    (1).费马小定理

    在是素数的情况下,对任意整数都有。 如果无法被整除,则有。 可以在为素数的情况下求出一个数的逆元,,即为逆元。
    题目中的数据范围1<=x<=10^9,p=1000000007,p是素数;
    所以x肯定就无法被p整除啊,所以最后就得出x^(p-2)为x的逆元啦。
    复杂度O(logn)

    const int mod = 1000000009;
    long long quickpow(long long a, long long b) {
    
        if (b < 0) return 0;
    
        long long ret = 1;
    
        a %= mod;
    
        while(b) {
    
            if (b & 1) ret = (ret * a) % mod;
    
            b >>= 1;
    
            a = (a * a) % mod;
    
        }
    
        return ret;
    }
    long long inv(long long a) {
    
        return quickpow(a, mod - 2);
    
    }
    
    不疯魔不成活
  • 相关阅读:
    2020/10/29
    2020/10/24
    2020/10/28
    2020/10/31周报
    linux shell 中判断字符串为空的正确方法
    20201107 千锤百炼软工人
    20201103 千锤百炼软工人
    20201109 千锤百炼软工人
    20201111 千锤百炼软工人
    20201105 千锤百炼软工人
  • 原文地址:https://www.cnblogs.com/gzr2018/p/9716225.html
Copyright © 2020-2023  润新知