扩展中国剩余定理
扩展中国剩余定理
前置芝士
中国剩余定理
作用
求同余方程余数无限制的通解。
推导过程
设 个方程解为 ,令 (注:此处不是乘积,而是 )
我们有 为前 个方程的通解
对于 个方程,求:
可化为:
由裴蜀定理得,方程若有解,则
通过 ,我们可以求得:
的一组通解
两边同乘 ,得:
由数学归纳法,循环 次即可
#include<bits/stdc++.h>
using namespace std;
typedef __int128 ll;
const int N=1e5+9;
ll n,m,ans,x,y,M;
l'l a[N],b[N];
inline ll exgcd(ll a,ll b,ll &x,ll &y){
if(!b) {x=1;y=0;return a;}
ll ret=exgcd(b,a%b,x,y);
ll z=x;x=y,y=z-(a/b)*y;
return ret;
}
int main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++) scanf("%lld%lld",&b[i],&a[i]);
ans=a[1],M=b[1];
for(int i=2;i<=n;i++)
{
ll tem=((a[i]-ans)%b[i]+b[i])%b[i];
ll G=exgcd(M,b[i],x,y);
x=x%b[i]*(tem/G);
ans=ans+M*x;
M=M*b[i]/G;//gcd(a,b)*lcm(a,b)=a*b
ans=(ans+M)%M;
}
printf("%lld\n",(long long)ans);
return 0;
}
例题
P4774 [NOI2018]屠龙勇士
思路
设 为前 个的答案,则这个方程应为:
稍加转移,可得
然后用扩欧求解,往下递推
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=100005;
int T,n,m,b[maxn],t[maxn];
ll a[maxn],p[maxn],mx;
multiset<ll>s;
inline void exgcd(ll A,ll B,ll &x,ll &y,ll &gcd){
if(!B) x=1,y=0,gcd=A;
else exgcd(B,A%B,y,x,gcd),y-=(A/B)*x;
}
ll ExCRT(){
ll ans=0,lcm=1,x,y,gcd,A,B,C;
for(int i=1;i<=n;i++){
A=(__int128)b[i]*lcm%p[i];
B=p[i];
C=(a[i]-b[i]*ans%p[i]+p[i])%p[i];
exgcd(A,B,x,y,gcd);x=(x%B+B)%B;
if(C%gcd) return -1;//如果C不是gcd(A,B)的倍数,那就不用算了
ans+=(__int128)(C/gcd)*x%(B/gcd)*lcm%(lcm*=B/gcd);
ans%=lcm;
//puts("----------");
//printf("%lld\n",ans);
}
if(ans<mx) ans+=((mx-ans-1)/lcm+1)*lcm;//砍的刀数不能小于龙的血量除以攻击力的最大值
return ans;
}
int main(){
scanf("%d",&T);
while(T--){
s.clear();mx=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<=n;i++) scanf("%lld",&p[i]);
for(int i=1;i<=n;i++) scanf("%d",&t[i]);
for(int i=1,x;i<=m;i++) scanf("%d",&x),s.insert(x);
for(int i=1;i<=n;i++) {
if(*s.begin()>a[i])b[i]=*s.begin(),s.erase(s.begin());
else b[i]=*(--s.upper_bound(a[i])),s.erase(s.lower_bound(b[i]));
s.insert(t[i]);//求龙的血量除以攻击力的最大值
mx=max(mx,(a[i]-1)/b[i]+1);
}
//for(int i=1;i<=n;i++)
// printf("%d ",(a[i]-1)/b[i]+1);
printf("%lld\n",ExCRT());
}
}
(大力感谢AlanSP)
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· Vite CVE-2025-30208 安全漏洞
· 《HelloGitHub》第 108 期
· MQ 如何保证数据一致性?
· 一个基于 .NET 开源免费的异地组网和内网穿透工具