





1 P4777 【模板】扩展中国剩余定理(EXCRT)
https://www.luogu.com.cn/problem/P4777
cpp
#include <bits/stdc++.h>
using namespace std;
#define lll __int128
using ll=long long;
const int N=1e5+5,M=1e5+5;
const lll inf=1ll<<60;
int n;
//返回gcd(a,b),并输出x,y的特解
lll exgcd(lll a,lll b,lll &x,lll &y){
if(!b){//递归边界:b=0
x=1,y=0;
return a;
}else{
lll aa=exgcd(b,a%b,y,x);
//y=原y-(a/b)*x;
y-=a/b*x;
return aa;
}
}
lll A,B;lll x,y;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
ll a,b;
cin>>n;
A=1;B=0;//mod1一定等于0
for(int i=1;i<=n;i++){
cin>>a>>b;
lll gd=exgcd(A,a,x,y);
x=(B-b)/gd*x;
B=B-A*x;
A=(ll)a/gd*A;
B=(B%A+A)%A;
}ll ans=(B%A+A)%A;
cout<<ans<<'\n';
}
2 P3868 [TJOI2009] 猜数字 题解
https://www.luogu.com.cn/problem/P3868


cpp
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
ll a[20],b[20];
int k;
void exgcd(ll a,ll b,ll &x,ll &y){
if(!b){//递归边界:b=0
x=1,y=0;
return ;
}else{
exgcd(b,a%b,y,x);
//y=原y-(a/b)*x;
y-=a/b*x;
}
}
ll qmul(ll a,ll b,ll mod)
{
ll ans=0;
while(b>0)
{
if(b&1) ans=(ans+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return ans;
}
ll china(){
ll ans=0,lcm=1,x,y;
for(int i=1;i<=k;i++){
lcm*=b[i];
}for(int i=1;i<=k;i++){
ll tp=lcm/b[i];
exgcd(tp,b[i],x,y);
x=(x%b[i]+b[i])%b[i];
ans=(ans+qmul(qmul(tp,x,lcm),a[i],lcm))%lcm;
}return (ans+lcm)%lcm;
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>k;
for(int i=1;i<=k;i++){
cin>>a[i];
}for(int i=1;i<=k;i++){
cin>>b[i];
}for(int i=1;i<=k;i++){
a[i]=(a[i]%b[i]+b[i])%b[i];
}cout<<china();
}
3 东风谷早苗与博丽灵梦
https://ac.nowcoder.com/acm/contest/120564/D
cpp
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
#define int __int128_t
void gcd(int a,int b,int &x,int &y){
if(!b){//递归边界:b=0
x=1,y=0;
return ;
}else{
gcd(b,a%b,y,x);
//y=原y-(a/b)*x;
y-=a/b*x;
}
}
__int128_t read(){
char str[100];
scanf("%s",str+1);
__int128_t ans=0;
for(int i=1;i<=strlen(str+1);i++){
ans=ans*10+str[i]-'0';
}return ans;
}void print(__int128_t a){
if(a>9)print(a/10);
putchar(a%10+'0');
}
void so(){
int a,b,c,x=0,y=0;
c=read(),a=read(),b=read();
int g=__gcd(a,b);
if((c%g)!=0){
cout<<"No\n";
return;
}
gcd(a,b,x,y);//求解a*x+b*y=g
int w=c/g;
x*=w;y*=w;
int da=a/g;
int db=b/g;
int k=(y-x)/(da+db);
int ans=1e19,s1,s2;
auto check=[&](int v){
int nx=x+v*db;
int ny=y-v*da;
if(nx>=0&&ny>=0&&max(nx,ny)<ans){
ans=max(nx,ny);
s1=nx;
s2=ny;
}
};
for(int i=k-100;i<=k+100;i++){
check(i);
}
// 在c1=0附近搜索(即x + k*db = 0,k ≈ -x/db)
for (int i = -x / db - 100; i <= -x / db + 100; i++) {
check(i);
}
// 在c2=0附近搜索(即y - k*da = 0,k ≈ y/da)
for (int i = y / da - 100; i <= y / da + 100; i++) {
check(i);
}
// 如果没有找到有效解(ans还是初始值),输出No
if (ans > 2e18) {
cout << "No\n";
} else {
cout << "Yes\n";
print(s1);
cout << ' ';
print(s2);
cout << '\n';
}
}signed main(){
int t;t=read();
while(t--){so();}
}