数论经典算法代码
摘自算法竞赛入门经典(第2版)
欧几里得求gcd
int gcd (int a, int b)
{
return b==0 ? a : gcd(b,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); }
}
Eratosthenes筛法(三个trick)
int a[100000];
void eratosthenes(int N)
{
memset(a,0,sizeof(a));
int m = sqrt(N+0.5);
for(int i=2;i<=m;++i) //这个地方到根号n
{
if(a[i]==0) //只需要对素数进行循环
for(int j=i;j<(N+i-1)/i;++j) //这里从i开始
a[i*j]=1;
}
}
mod n运算律
(a+b)%n == ((a%n)+(b%n))%n
(a-b)%n == ((a%n)-(b%n)+n)%n //0%n会出错 注意
(a*b)%n == (a%n)*(b%n)%n //注意(a%n)*(b%n)的溢出问题, 最好用下面的写法
int mul_mod(int a, int b, int n)
{
a %= n; b %= n;
return (int)((long long)a * b % n);
}
高精度整数mod
scanf("%s%d",n,&m) //n%m, n<10^100, m<10^9
int len = strlen(n);
int ans = 0;
for(int i=0;i<len;i++)
ans = (int)(((long long)ans *10 + n[i] - '0') % m);
printf("%d\n",ans);
快速幂mod
int pow_mod(int a, int n, int m){ // a^n%m
if(n==0) return 1;
int x = pow_mod(a, n/2, m);
long long ans = (long long) x * x % m;
if(n%2==1) ans = ans * a % m;
return (int)ans;
}