用中国剩余定理要求各个数直接互质,而扩展中国剩余定理则没有这个要求。
扩展中国剩余定理裸题,板子记好了。
因为数很大,过程可能会爆,所以可以用python,或者__int128.
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=105;
typedef __int128 ll;
ll n,m;
ll a[maxn],b[maxn];
inline void read(ll &ret)
{
char c;
while((c=getchar())&&(c>'9'||c<'0'));
ret=0;
while(c>='0'&&c<='9') ret=ret*10+c-'0', c=getchar();
}
inline void out(ll x)
{
if(x>9) out(x/10);
putchar(x%10+'0');
}
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b)
{
x=1; y=0;
return a;
}
ll d=exgcd(b,a%b,x,y);
ll temp=x;
x=y; y=temp-a/b*y;
return d;
}
ll excrt()
{
ll x,y,k;
ll M=a[1], ans=b[1]; //a[i]被余数,b[i]余数
for(int i=2;i<=n;++i)
{
ll a0=M, b0=a[i], c=(b[i]-ans);
ll gcd=exgcd(a0,b0,x,y), bg=b0/gcd;
if(c%gcd!=0) return -1;
x=(x*(c/gcd)%bg+bg)%bg;
ans+=x*M;
M=M/gcd*b0;
}
return ans;
}
int main()
{
read(n); read(m);
for(int i=1;i<=n;++i)
read(a[i]), read(b[i]);
ll ans=excrt();
if(ans==-1)
cout<<"he was definitely lying\n";
else if(ans>m)
cout<<"he was probably lying\n";
else out(ans),putchar('\n');
return 0;
}