数学知识
exgcd
对于 $\mathrm{ax+by=(a,b)}$ 的方程必然有解 $\mathrm{(x,y)}$.
$\mathrm{b=0}$ 时解为 $\mathrm{(1,0)}$.
$\mathrm{b}$ 不等于 $\mathrm{0}$ 时考虑递归求解.
考虑求出 $\mathrm{(b,a \mod b)}$ 时的解 $\mathrm{(x[2], y[2])}$ 则 $\mathrm{(x[1], y[1])}$ 为:
$\mathrm{x[1]=y[2]}$, $\mathrm{y[1]=x[2]-(a/b) \times y[2]}$.
若想求 $\mathrm{ax+by=c}$, 则 $\mathrm{c}$ 要整除 $\mathrm{(a,b)}$.
$\mathrm{x}$ 乘上 $\mathrm{c/(a,b)}$ 即为一个解,通解增量为 $\mathrm{b/(a,b)}$.
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
ll exgcd(ll a, ll b, ll &x, ll &y) {
if(!b) {
x = 1, y = 0;
return a;
}
ll gc = exgcd(b, a % b, x, y);
// 得到一组 x, y
ll t = x;
x = y;
y = t - (a / b) * y;
return gc;
}
int main() {
// setIO("input");
ll a, b, x0, y0;
scanf("%lld%lld", &a, &b);
ll gcd = exgcd(a, b, x0, y0);
ll mod = b / gcd;
printf("%lld", (x0 % mod + mod) % mod);
return 0;
}
青蛙的约会
来源:luoguP1516
推一下式子,是 $\mathrm{exgcd}$ 的形式,然后求出最小解即可.
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#define ll long long
#define pb push_back
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
ll exgcd(ll a, ll b, ll &x, ll &y){
if(!b) {
x = 1, y = 0;
return a;
}
ll gc = exgcd(b, a % b, x, y);
ll t = x;
x = y, y = t - (a / b) * y;
return gc;
}
int main() {
// setIO("input");
ll x, y, m, n, L, x0, y0;
scanf("%lld%lld%lld%lld%lld", &x, &y, &m, &n, &L);
ll a = m - n, b = L, c = y - x;
ll gcd = exgcd(a, b, x0, y0);
if(c % gcd) {
printf("Impossible");
}
else {
x0 *= (c / gcd);
ll mod = abs(b / gcd);
printf("%lld", (x0 % mod + mod) % mod);
}
return 0;
}
线性筛
核心思想是用每个合数最小的质因数将其筛掉.
如果 $\mathrm{i \mod p=0}$ 则说明 $\mathrm{p}$ 后面的质数都不是最小的质数.

浙公网安备 33010602011771号