【算法题】【数学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();}
}
相关推荐
寻寻觅觅☆10 小时前
东华OJ-基础题-106-大整数相加(C++)
开发语言·c++·算法
偷吃的耗子10 小时前
【CNN算法理解】:三、AlexNet 训练模块(附代码)
深度学习·算法·cnn
化学在逃硬闯CS11 小时前
Leetcode1382. 将二叉搜索树变平衡
数据结构·算法
ceclar12311 小时前
C++使用format
开发语言·c++·算法
Gofarlic_OMS12 小时前
科学计算领域MATLAB许可证管理工具对比推荐
运维·开发语言·算法·matlab·自动化
夏鹏今天学习了吗12 小时前
【LeetCode热题100(100/100)】数据流的中位数
算法·leetcode·职场和发展
忙什么果13 小时前
上位机、下位机、FPGA、算法放在哪层合适?
算法·fpga开发
董董灿是个攻城狮13 小时前
AI 视觉连载4:YUV 的图像表示
算法
ArturiaZ14 小时前
【day24】
c++·算法·图论
大江东去浪淘尽千古风流人物14 小时前
【SLAM】Hydra-Foundations 层次化空间感知:机器人如何像人类一样理解3D环境
深度学习·算法·3d·机器人·概率论·slam