算法模板_数论问题
欧几里得算法
求两个正整数的最大公约数,时间复杂度O(logn)。
#define ll long long ll gcd(ll a,ll b)//辗转相除法 { return b?gcd(b,a%b) : a; }
扩展欧几里得算法
裴蜀定理:若 a,b 是整数,且 gcd(a,b)=d,那么对于任意的整数 x,y,ax+by 都一定是 d 的倍数,特别地,一定存在整数 x,y,使 ax+by=d 成立。
扩展欧几里得算法可以在 O(logn) 的时间复杂度内求出系数 x,y。
int exgcd(int a, int b, int &x, int &y) { if (!b) { x = 1; y = 0; return a; } int d = exgcd(b, a % b, y, x); y -= (a/b) * x; return d; }
线性筛素数
可以在 O(n) 的时间复杂度内求出 1∼n之间的所有质数。
int primes[N], cnt; bool st[N]; void get_primes(int n) { for (int i = 2; i <= n; i ++ ) { if (!st[i]) primes[cnt ++ ] = i; for (int j = 0; primes[j] <= n / i; j ++ ) { st[primes[j] * i] = true; if (i % primes[j] == 0) break; } } }