OI loves Math(二)——有理数取模

在一些期望值的题目里,经常会遇到这么一句话:

输出期望值模 998244353 的结果。

然后你就万脸懵逼了,分数怎么取模?
别急!


看这个有理数取余,它里面直接给出了定义:

这个值被定义为 bxa (mod p) 的解。

但问题来了,怎么求出 x 呢?
反推回去呗!

Part 1 x

x=a÷b=a×1b
但这不还是成小数了吗?
想想倒数的定义:

xy=1 ,则 x,y 互为倒数。

我们这也一样,也就是说,在模 10 意义下,37 互为倒数,也称作逆元。
但是怎么求出 b 的逆元呢?

Part 2 b 的逆元

第一种 费马小定理

如果 p 是一个质数,而整数 a 不是 p 的倍数,则有 ap11 (mod p)。——百度

ap11 (mod p)

ap21a

懂了吧?

第二种 ExGcd

先咕着,日后再更。

Part 3 代码

注意这里 A,B 很大,需要用高精除法取一下模。

#include <bits/stdc++.h>
using namespace std;

char A[10005], B[10005];

const long long mod = 19260817;

long long qpow(long long base, long long exp, long long mod) {
	long long ans = 1;
	while (exp) {
		if (exp & 1) {
			ans = (ans * base) % mod;
		}
		exp >>= 1;
		base = (base * base) % mod;
	}
	return ans % mod;
}

int main() {
	fgets(A, 1048576, stdin);
	fgets(B, 1048576, stdin);
	int n = strlen(A), m = strlen(B);
	long long a = 0, b = 0;
	for (int i = 0; i < n; i++) {
		a = (a * 10 + (A[i] - '0')) % mod;
	}
	for (int i = 0; i < m; i++) {
		b = (b * 10 + (B[i] - '0')) % mod;
	}
	if (!b) {
		printf("Angry!");
	} else {
		long long b_inv = qpow(b, mod - 2, mod);
		printf("%lld", (a * b_inv) % mod);
	}
	return 0;
}

Bye!

posted @   A-Problem-Solver  阅读(690)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示