线性同余方程
形如 的方程称为线性同余方程,从区间 中求解 .
逆元求解。
假设 ,两边同时乘上 即可。
设 ,左侧始终可以 被 整除,若右侧不可则无解。
若右侧可以被 整除,则将 同时除以 ,得到 .
此时 ,回到上面的情况。
所以解为 ,个数为 个或 个。
扩展欧几里得算法求解。
方程可以写成 ,有解的充要条件是 .
先算出 ,之后两边同时除以 再乘上 即为一组解。
即 .
若 的一组特解为 ,则任意解可以写成 为任意整数。
对于求一个最小整数解,
给定 ,求 .
读入过大,但是是同余方程,可以在读入时将其进行取模,当 是 的倍数时不存在逆元,分母为零,无解。
constexpr int N=5e6+6,mod=19260817; template<class T>inline T readmod(T&x){ char c=getchar();x=0; while(c<'0'||c>'9')c=getchar(); while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),x%=mod,c=getchar(); return x; } signed main(){ int a,b,x,y; readmod(a),readmod(b); if(b==0){ cout<<"Angry!"; return 0; } exgcd(b,mod,x,y); x=(x%mod+mod)%mod; cout<<a*x%mod; return 0; }
求解二元一次不定方程 .
首先找到特解 ,假设将 扩大为 , 缩小为 .
则有,.
解得,,由于需要获得最小的正整数,所以 .
故,.
可以得到 ,也就是 的最小增幅。
考虑将 调整至最小正整数解。
假设 ,设 ,则 .
若 ,则 .
若 为最小正整数时 ,则正整数解的个数为 .
注意调整 是应该系数在前面, 在后面,来避免上下取整造成的误差与错误。
while(t--){ int a,b,c,x,y; cin>>a>>b>>c; int g=exgcd(a,b,x,y); if(c%g){ cout<<-1<<'\n'; continue; } x*=c/g; y*=c/g; int p=b/g,q=a/g,k; if(x<0){ k=ceil((1.0-x)/p); x+=k*p; y-=k*q; } else{ k=(x-1)/p; x-=k*p; y+=k*q; } if(y>0)cout<<(y-1)/q+1<<' '<<x<<' '<<(y-1)%q+1<<' '<<x+(y-1)/q*p<<' '<<y<<'\n'; else cout<<x<<' '<<y+(int)ceil((1.0-y)/q)*q<<'\n';/*注意要对ceil强制转换才能当做系数*/ }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】