同余方程 P2613 (4/11补档正确做法)
P2613 同余模板
蒻蒟看不懂扩展欧几里得,就死记硬背了
//求关于 x 的同余方程 ax≡1(modb) 的最小正整数解
LL x,y;//目前方程真正的解
void work(LL a,LL b)
{
//当前目的:求解 ax + by = gcd(a, b) 这么一个方程
if(b==0)//a, b不断改变的过程中,b最终必然会成为0
{
//在 b = 0 时方程还要成立? 使 x = 1, y = 0 ,必然成立
x=1;
y=0;
return;
}
work(b,a%b);
LL tempx=x;
x=y;
y=tempx-a/b*y;
}
int main() {
LL a,b;
cin>>a>>b;
work(a,b);
x=(x%b+b)%b;//我们求出来的x必然满足方程,但不一定是最小正整数解,所以要进行答案处理
cout<<x;//如果 ax≡1(modb) 中的 1 为 μ ,则要变为 μ * x % b;
return 0;
}
另外,由于数据过大,需要使用快读的同时取模
inline LL read()
{
LL res=0;
char ch=getchar();
while(!isdigit(ch) && ch!=EOF) ch=getchar();
while(isdigit(ch))
{
res=(res<<3)+(res<<1)+(ch-'0');
//若数很大,则取模 res%=MOD;
ch=getchar();
}
return res;
}
(补档内容)
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
LL x, y, gcd;
// 扩展欧几里得算法
void exgcd(LL a, LL b) {
if (b == 0) {
x = 1, y = 0;
gcd = a;
return;
}
exgcd(b, a % b);
LL temp = x;
x = y;
y = temp - (a / b) * y;
}
// 计算 ax ≡ c (mod b) 的最小非负整数解
LL solve(LL a, LL b, LL c) {
exgcd(a, b);
// 如果 c 不是 gcd(a, b) 的倍数,则无解
if (c % gcd != 0) return -1;
// 计算初始解 x0 = x * (c / gcd)
x *= c / gcd;
b = abs(b / gcd); // 约简 b,确保 x 归一化到 [0, b)
// 归一化 x 到 [0, b)
x = (x % b + b) % b;
return x;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
LL a, b, c;
cin >> a >> b >> c;
LL result = solve(a, b, c);
if (result == -1)
cout << "No solution" << endl;
else
cout << result << endl;
return 0;
}