POJ-2891 Strange Way to Express Integers(拓展中国剩余定理)

放一个写的不错的博客:https://www.cnblogs.com/zwfymqz/p/8425731.html
POJ好像不能用__int128。

#include <iostream>
#include <stdio.h>

typedef long long ll;
const int maxn=1e6+10;
ll m[maxn],r[maxn];

void exgcd(ll a,ll b,ll &x,ll &y)
{
	if (b==0) {
		x=1;
		y=0;
		return ;
	}
	exgcd(b,a%b,x,y);
	ll t=x;
	x=y;
	y=t-(a/b)*y;
}

ll inv(ll a,ll b)
{
	ll x,y;
	exgcd(a,b,x,y);
	while (x<0) {
		x+=b;
	}
	return x;
}

ll read()
{
	char ch=getchar();
	ll x=0,f=1;
	while (ch<'0'||ch>'9') {
		if (ch=='-') {
			f=-1;
		}
		ch=getchar();
	}
	while (ch>='0'&&ch<='9') {
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x;
}

void print(ll x)
{
	if (x<0) {
		putchar('-');
		x=-x;
	}
	if (x>9) {
		print(x/10);
	}
	putchar(x%10+'0');
}

ll gcd(ll a,ll b)
{
	return b==0?a:gcd(b,a%b);
}

int main()
{
	ll k;
	while (scanf("%lld",&k)!=EOF) {
		for (int i=1;i<=k;i++) {
			m[i]=read();
			r[i]=read();
		}
		bool flag=0;
		for (int i=2;i<=k;i++) {
			ll g=gcd(m[i],m[i-1]);
			if ((r[i]-r[i-1])%g!=0) {
				flag=1;
				break;
			}
			r[i]=(inv(m[i-1]/g,m[i]/g)*(r[i]-r[i-1])/g)%(m[i]/g)*m[i-1]+r[i-1];
			m[i]=m[i]*m[i-1]/g;
			r[i]=(r[i]%m[i]+m[i])%m[i];		
		}
		if (flag) {
			puts("-1");
		}	
		else {
			print(r[k]);
			puts("");
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/xyqxyq/p/12328885.html