初等数论合集

typedef long long LL;

欧拉筛法即线性筛

const int maxm = 10000000 + 5;
bool isprime[maxm]; //若1为素数 若0不是素数
int su[maxm];
void prime()
{
    int cnt = 0;
    memset(isprime, true, sizeof isprime);
    memset(su, 0, sizeof su);
    isprime[0] = isprime[1] = false; // 0 和 1 不是素数
    for (int i = 2; i <= maxm; i++)
    {
        if (isprime[i])
            su[++cnt] = i;
        for (int j = 1; j <= cnt && i * su[j] <= maxm; j++)
        {
            isprime[i * su[j]] = false;
            if (i % su[j] == 0)
                break;
        }
    }
}

欧几里德 

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

扩展欧几里德

int ex_gcd(int a, int b, int &x, int &y)
{
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    else
    {
        int d = ex_gcd(b, a % b, x, y);
        int t = x;
        x = y;
        y = t - (a / b) * y;
        return d;
    }
}

快速幂

LL qpow(LL a, LL b, LL c)
{
    LL ans = 1;
    while (b)
    {
        if (b & 1)
            ans = ans * a % c;
        a = a * a % c;
        b = b >> 1;
    }
    return ans;
}

乘法逆元

这位博主说得挺好的https://www.cnblogs.com/zjp-shadow/p/7773566.html

扩展欧几里德求逆元

void Ex_gcd(LL a, LL b, LL &x, LL &y)
{
    if (!b)
        x = 1, y = 0;
    else
        Exgcd(b, a % b, y, x), y -= a / b * x;
}
int main()
{
    LL x, y;
    Ex_gcd(a, p, x, y);
    x = (x % p + p) % p;
    printf("%d\n", x); //x是a在mod p下的逆元
}

费马小定理即快速幂求逆元

LL Inv(LL a, LL p)
{
    return qpow(a, p - 2, p);
}

线性递推求逆元

LL n, p;
    cin >> n >> p;
    inv[1] = 1;
    for (int i = 2; i <= n; i++)
    {
        inv[i] = p - p / i * inv[p % i] % p;
    }
扫描二维码关注公众号,回复: 8958950 查看本文章
发布了59 篇原创文章 · 获赞 22 · 访问量 3838

猜你喜欢

转载自blog.csdn.net/qq_44115065/article/details/104077830