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 查看本文章