数论经典算法代码

数论经典算法代码

摘自算法竞赛入门经典(第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;
}

猜你喜欢

转载自blog.csdn.net/weixin_37730368/article/details/88920764