扩展中国剩余定理 P4777 【模板】扩展中国剩余定理(EXCRT)

复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=1e5+5;
 5 ll a[N],mod[N],n;
 6 ll read()
 7 {
 8     ll x=0,f=1;char ch=getchar();
 9     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
10     while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
11     return x*f;
12 }
13 ll exgcd(ll a,ll b,ll &x,ll &y)
14 {
15     if(!b)
16     {
17         x=1,y=0;
18         return a;
19     }
20     ll d=exgcd(b,a%b,x,y);
21     ll t=x;
22     x=y;y=t-a/b*y;
23     return d;
24 }
25 
26 ll quimul(ll a,ll n, ll p)
27 {
28     ll ans=0;
29     while(n)
30     {
31         if(n&1)ans=(ans+a)%p;
32         n>>=1;
33         a=(a+a)%p;
34     }
35     return ans;
36 }
37 int main()
38 {
39     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
40     n=read();
41     for(int i=1;i<=n;i++)mod[i]=read(),a[i]=read();
42 
43     ll ans=a[1],md1=mod[1];
44     for(int i=2;i<=n;i++)
45     {
46         ll a2=a[i],md2=mod[i],x=0,y=0,r=((a2-ans)%md2+md2)%md2;
47         ll gd=exgcd(md1,md2,x,y);
48         if(r%gd){return -1;}
49         ll lcm_=md1/gd*md2;
50         if(x<0)x+=md2;
51         x=quimul(r/gd,x,md2);
52         ans=(quimul(x,md1,lcm_)+ans)%lcm_;
53         md1=lcm_;
54     }
55     cout<<ans<<"\n";
56     return 0;
57 }
复制代码

 

posted @   matt-11  阅读(40)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示