P4777 模板扩展中国剩余定理(EXCRT)
Posted cherish-lin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4777 模板扩展中国剩余定理(EXCRT)相关的知识,希望对你有一定的参考价值。
题目描述
给定 nnn组非负整数 ai,bia_i, b_iai?,bi?,求解关于 xxx的方程组x≡b1 (mod a1)x≡b2 (mod a2)...x≡bn (mod an)\begincases x \equiv b_1\ (\rm mod\ a_1) \\ x\equiv b_2\ (\rm mod\ a_2) \\ ... \\ x \equiv b_n\ (\rm mod\ a_n)\endcases??????????x≡b1? (mod a1?)x≡b2? (mod a2?)...x≡bn? (mod an?)?的最小非负整数解。
输入输出格式
输入格式:输入第一行包含整数 nnn。
接下来 nnn行,每行两个非负整数 ai,bia_i, b_iai?,bi?。
输出格式:输出一行,为满足条件的最小非负整数 xxx。
输入输出样例
说明
n≤105,1≤ai≤1012,0≤bi≤1012,bi<ain \leq 10^5, 1 \leq a_i \leq 10^12, 0 \leq b_i \leq 10^12, b_i < a_in≤105,1≤ai?≤1012,0≤bi?≤1012,bi?<ai?,保证答案不超过 101810^181018。
请注意程序运行过程中进行乘法运算时结果可能有溢出的风险。
数据保证有解
#include<iostream> #include<cstring> #include<string> #include<cmath> #include<stdio.h> using namespace std; typedef long long ll; const int maxn=100010; ll a[maxn],b[maxn],n; ll exgcd(ll a,ll b,ll &x,ll &y) if(b==0) x=1,y=0; return a; else ll d=exgcd(b,a%b,y,x); y-=a/b*x; return d; ll quickmul(ll a,ll b,ll mod) ll ans=0; while(b) if(b&1)ans=(ans+a)%mod; a=(a+a)%mod; b>>=1; return ans; ll solve() ll M=b[1]; ll ans=a[1]; for(int i=2;i<=n;i++) ll x,y; ll g=exgcd(M,b[i],x,y); ll c=((a[i]-ans)%b[i]+b[i])%b[i];//将其变正 x=quickmul(x,c/g,b[i]); b[i]/=g; ans+=x*M; M*=b[i]; ans=(ans%M+M)%M; return ans; int main() scanf("%lld",&n); for(int i=1;i<=n;i++)cin>>b[i]>>a[i];//这里为了习惯,反过来输入了 printf("%lld\n",solve()); return 0;
以上是关于P4777 模板扩展中国剩余定理(EXCRT)的主要内容,如果未能解决你的问题,请参考以下文章