除法取模运算(公式法)

注意,除法是指算术除法后向下取整,即计算机中的整数除法
如果遇到(a/b)%m的问题,直接运算a/b然后取模是错误的,这时,我们往往需要求出b的逆元,然后将式子改为:(a*b的逆元)%m的形式,此时先做乘法再取模就正确了。

除此之外,还有一种方法,就是用以下公式求解:

x/d%m=x%(d*m)/d

证明:

\[\begin{aligned}\frac{x}{d} \%m &= \frac{x}{d}-m\cdot \frac{x}{d\cdot m}\\\frac{x\%(d\cdot m)}{d}&=\frac{x-d\cdot m\cdot \frac{x}{d\cdot m}}{d}\\&=\frac{x}{d}-m\cdot \frac{x}{d\cdot m}\end{aligned}\]

例题

[原题链接](Problem - I - Codeforces)

题目大意

给两个整数n,m。求\(\frac{1}{n}\) 小数点后第m位。\(1\leq n \leq 10^5,1\leq m \leq 10^9\)

样例1

输入

3 5

输出

3

样例2

输入

233 23

输出

5

思路

\(k=\frac{1}{n}\),则求k小数点后第1位,就是把k乘以10然后取个位,求k小数点后第2位,就是k乘以100然后取个位,以此类推

故求k小数点后第m位就是\(\frac{10^m}{n} \% 10\),然后用公式转化为:\(\frac{10^m \%(10\cdot n)}{n}\)。然后就可以使用快速幂计算。

AC代码

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

i64 n, m;

i64 qp(i64 a, i64 b) {
	i64 res = 1;
	while (b) {
		if (b & 1) {
			res = res * a % (10 * n);
			b--;
		}
		a = a * a % (10 * n);
		b /= 2;
	}
	return res;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> n >> m;
	cout << qp(10, m) / n;
	
	return 0;
}
06-25 16:32