P4777 【模板】扩展中国剩余定理(EXCRT)关于快速乘的一点疑惑
查看原帖
P4777 【模板】扩展中国剩余定理(EXCRT)关于快速乘的一点疑惑
313668
DoubleBean楼主2021/2/28 13:26

我刚开始提交的代码是这样子的

#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
const ll MAXN = 1e6 + 10;
ll m[MAXN], c[MAXN];
ll gcd(ll a, ll b)
{
	return b == 0 ? a : gcd(b, a%b);
}
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 temp = y;
	y = x - a / b * y;
	x = temp;
}
ll inv(ll a, ll b)
{
	ll x, y;
	exgcd(a, b, x, y);
	return (x % b + b) % b;
}
ll quick_mult_mod(ll a, ll b, ll mod) // 快速乘
{
	ll result = 0; // result初始化为0
	while (b){
		if (b & 1) result = (result + a) % mod;
		a = (a + a) % mod;
		b >>= 1;
	}
	return result;
}
int main(){
	ll k;
	scanf("%lld", &k);
	for (ll i = 1; i <= k; i++){
		scanf("%lld%lld", &m[i], &c[i]);
	}
	bool flag = 1;
	for (ll i = 2; i <= k; i++){
		ll M1 = m[i - 1], M2 = m[i], C1 = c[i - 1], C2 = c[i], GCD = gcd(M1, M2);
		if ((C2 - C1) % GCD){
			flag = 0;
			break;
		}
		m[i] = (M1 * M2) / GCD;

		c[i] = inv(M1 / GCD, M2 / GCD) * (C2 - C1) / GCD % (M2 / GCD) * M1 + C1;
		c[i] = (c[i] % m[i] + m[i]) % m[i];
	}
	printf("%lld\n", flag ? c[k] : -1);
	return 0;
}

结果是后面三个测试点WA了,我就想着可能是没有用快速乘所以导致爆掉,就加了个快速乘上去

#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
const ll MAXN = 1e6 + 10;
ll m[MAXN], c[MAXN];
ll gcd(ll a, ll b)
{
	return b == 0 ? a : gcd(b, a%b);
}
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 temp = y;
	y = x - a / b * y;
	x = temp;
}
ll inv(ll a, ll b)
{
	ll x, y;
	exgcd(a, b, x, y);
	return x;
	//return (x % b + b) % b;
}
ll quick_multi_mod(ll a, ll b, ll mod)
{
	ll ans = 0;
	while (b){
		if (b & 1) ans = (ans + a) % mod;
		a = (a + a) % mod;
		b >>= 1;
	}
	return ans;
}
int main(){
	ll k;
	scanf("%lld", &k);
	for (ll i = 1; i <= k; i++){
		scanf("%lld%lld", &m[i], &c[i]);
	}
	bool flag = 1;
	for (ll i = 2; i <= k; i++){
		ll M1 = m[i - 1], M2 = m[i], C1 = c[i - 1], C2 = c[i], GCD = gcd(M1, M2);
		if ((C2 - C1) % GCD){
			flag = 0;
			break;
		}
		m[i] = (M1 * M2) / GCD;
		c[i] = quick_multi_mod(inv(M1 / GCD, M2 / GCD), ((C2 - C1) / GCD), (M2 / GCD)) * M1 + C1; // 这一行代码改成用快速乘处理
		c[i] = (c[i] % m[i] + m[i]) % m[i];
	}
	printf("%lld\n", flag ? c[k] : -1);
	return 0;
}

然后把c[i]那一行代码改成用快速乘来处理(就是倒数第4行代码),但结果就显示不出来了,只是改成快速乘处理,为什么就错了,快速乘的代码块那里也没有错啊,各位大佬救救我

2021/2/28 13:26
加载中...