【算法题】【数学3.2】【中国剩余定理】






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();}
}
相关推荐
YuanDaima204821 分钟前
二分查找基础原理与题目说明
开发语言·数据结构·人工智能·笔记·python·算法
阿Y加油吧27 分钟前
两道中等 DP 题拆解:打家劫舍 & 完全平方数
算法·leetcode·动态规划
七颗糖很甜29 分钟前
python实现全国雷达拼图数据的SCIT风暴识别
python·算法·scipy
B325帅猫-量子前沿技术研究所2 小时前
PSD和FFT的关系
人工智能·算法
闻缺陷则喜何志丹2 小时前
【排序】P6149 [USACO20FEB] Triangles S|普及+
c++·算法·排序·洛谷
avocado_green2 小时前
【LeetCode】90. 子集 II
算法·leetcode
tankeven2 小时前
HJ178 【模板】双指针
c++·算法
君义_noip2 小时前
信息学奥赛一本通 4131:【GESP2506六级】学习小组 | 洛谷 P13015 [GESP202506 六级] 学习小组
算法·动态规划·gesp·信息学奥赛
6Hzlia3 小时前
【Hot 100 刷题计划】 LeetCode 72. 编辑距离 | C++ 经典 DP 增删改状态转移
c++·算法·leetcode
穿条秋裤到处跑3 小时前
每日一道leetcode(2026.04.16):距离最小相等元素查询
算法·leetcode·职场和发展