求助大佬!!!过不了样例!!!
查看原帖
求助大佬!!!过不了样例!!!
866154
fcy20180201楼主2023/7/20 12:32

求助大佬!!!为什么这份代码连样例都过不了?(推导和题解里第一篇差不多,主要的就是合并同余方程组)

#include<bits/stdc++.h>
using namespace std;
#define int long long
/*
推导:  (此处同余符号写作==,等于号写作=) 
		n组同余方程:x==r[1] mod m[1]
                	x==r[2] mod m[2] 
                               ...
                    x==r[n] mod m[n]
    	考虑每次合并方程.
		设要合并的方程为:x==a1 mod b1
						  x==a2 mod b2 
		分解成等式:x=k1b1+a1=k2b2+a2
		后两项移项:k1b1+(-k2)b2=a2-a1
		换元,令g=gcd(b1,b2),p1=b1/g,p2=b2/g 
		易证p1与p2互质,则将b1,b2代入:
 		       m1=g*p1,m2=g*p2 
 		得:
 		     g*k1p1+g*(-k2)p2=a2-a1
 		两边同除以g:
		 	 k1p1+(-k2)p2=(a2-a1)/g 
		根据裴蜀定理,原方程(k1b1+(-k2)b2=a2-a1)有解当且仅当g|a2-a1 .
		     则现方程右式(a2-a1)/g为整数.
		而左式中p1与p2互质,则可以先使用exgcd求出k1p1+(-k2)p2=1的解.
		不妨设得到的某组解为t1,t2,即:
		      t1p1+(-t2)p2=1
		方程两边同乘(a2-a1)/g,得:
		      t1(a2-a1)/g*p1+(-t2)(a2-a1)/g*p2=(a2-a1)/g
		即k1和k2的一组解是:
		      k1=t1(a2-a1)/g,k2=(-t2)(a2-a1)/g
		即得到x得一个解:x=a1+k1b1=a1+t1(a2-a1)/g*b1 .
		根据某个定理,x得通解为x=x'+s*lcm(b1,b2) .
		转化为同余方程:x==x'mod(lcm(b1,b2))
		可以继续进行合并,推导结束. 
*/
int n,r[1000005],m[100005],M;

int gcd(int x,int y){
	while(x && y)(x>=y?x%=y:y%=x);
	return x+y;
}

int lcm(int x,int y){
	return x/gcd(x,y)*y;
}

void EXgcd(int a,int b,int &x,int &y){
	if(!b)x=1,y=0;
	else EXgcd(b,a%b,y,x),y=a/b*x;
	return ;
}

void EXcrt(int num){
	M=lcm(m[num],m[num+1]);
	int a1=r[num],b1=m[num],a2=r[num+1],b2=m[num+1];
	int g=gcd(b1,b2),p1=b1/g,p2=b2/g;
	int t1,t2;EXgcd(p1,p2,t1,t2);
	r[num+1]=(a1+t1*(a2-a1)/g*b1)%M,m[num+1]=M;
	return ;	
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin>>n;
	for(int i=0;i<n;i++)cin>>m[i]>>r[i];
	for(int i=0;i<n-1;i++)EXcrt(i);
	cout<<r[n-1]%m[n-1];
	return 0;
}  
2023/7/20 12:32
加载中...