codeforces 1114C Trailing Loves (or L'oeufs?) (数论)

https://codeforces.com/contest/1114/problem/C

题意

输入一个n和b。 1 ≤ n ≤ 1 0 18 1\leq n\leq 10^{18} 1n1018 2 ≤ b ≤ 1 0 12 2 \leq b \leq 10^{12} 2b1012
输出n! 在b进制下,末尾连续0的个数。
例如5 2
120 = 1111000
末尾连续0的个数为3。

题解

n ! = x k ∗ b y k + x k − 1 ∗ b y k − 1 + ⋯ + x 1 ∗ b y 1 n! = x_k*b^{y_k}+x_{k-1}*b^{y_{k-1}}+\dots+x_1*b^{y_1} n!=xkbyk+xk1byk1++x1by1
转换成的b进制数为 x k x k − 1 … x 1 x_kx_{k-1}\dots x_1 xkxk1x1
n !   m o d   b k = = 0 n! \ mod \ b^k == 0 n! mod bk==0时, x k x_k xk就为0。
所以只要知道何时不整除 b k b^k bk就可以了。
但是n的范围特别大,不可能算出n的阶乘。
所以考虑质因子分解。
n ! = p 1 m 1 p 2 m 2 … p r m r n!=p_1^{m1}p_2^{m2}\dots p_r^{mr} n!=p1m1p2m2prmr
b = p 1 k 1 p 2 k 2 … p r k r b=p_1^{k1}p_2^{k2}\dots p_r^{kr} b=p1k1p2k2prkr
算出b中的每个质因子p在 n ! n! n!中的贡献,例如2在6!中出现的次数tmp是6/2+6/4=4。即因子2作为2出现的次数加上作为4出现的次数。以此类推。
然后tmp/k1即使 p k 1 p^{k1} pk1出现的次数。
最后取所有的出现次数的最小值便是 b r b^r br中的r。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
	ll n,b;
	cin >> n >> b;
	ll ans = 1ll<<60;
	for(ll i = 2; i <= b; ++i) {
		if(1ll*i*i > b) i = b;
		// cout << i << endl;
		int cnt = 0;
		if(b%i == 0) {
			while(b%i == 0) {
				b /= i;
				cnt++; // p^cnt
			}
			ll mul = 1;
			ll tmp = 0;
			while(n/i >= mul) {
				mul*=i;
				tmp += n/mul;
				
			}
			ans = min(ans, tmp/cnt);
		}
	}
	cout << ans << endl;
	return 0;
}
### 关于 Floor 和 Ceil 函数在编程中的实现 Floor 和 Ceil 是两个常见的数学函数,在许多算法竞赛平台(如 Codeforces)上经常被用于解决涉及整数除法、取模运算等问题。以下是它们的定义以及如何在程序设计中实现这些功能。 #### 定义 - **Floor Function**: 对实数向下取整,返回不大于该数值的最大整数[^1]。 - **Ceil Function**: 对实数向上取整,返回不小于该数值的最小整数[^2]。 #### 实现方法 大多数现代编程语言都提供了内置库来支持 floor 和 ceil 的计算: ##### 使用标准库 在 C++ 中可以利用 `<cmath>` 库中的 `floor` 和 `ceil` 方法完成相应操作: ```cpp #include <iostream> #include <cmath> int main() { double num = 3.7; std::cout << "Floor value: " << static_cast<int>(std::floor(num)) << "\n"; // 输出 3 std::cout << "Ceil value: " << static_cast<int>(std::ceil(num)) << "\n"; // 输出 4 } ``` 然而需要注意的是,当处理负数时,这两个函数的行为可能不符合直觉。例如,`floor(-2.5)` 返回 `-3` 而不是 `-2`,因为它是严格意义上的“下限”。 如果目标是在没有浮点误差的情况下仅针对正整数执行类似的逻辑,则可以通过简单的算术表达式手动模拟这两种行为而无需调用任何外部库函数: - 手动实现 Floor: 当 a / b 结果为非零余数时保持原样;否则减去一个小量使得最终结果总是趋向更小的方向移动直到达到下一个较低的整数位置为止。 - 手动实现 Ceil: 如果存在剩余部分则增加到下一更高的整数值上去;如果没有多余的部分,那么它本身已经是天花板高度了. 具体代码如下所示: ```python def manual_floor(a, b): return (a // b) def manual_ceil(a, b): if a % b == 0: return a // b else: return (a // b) + 1 ``` 上述 Python 版本展示了如何通过基本运算符构建自己的版本而不依赖额外模块的帮助[^3]. ### 示例应用案例分析 考虑到实际应用场景下的复杂度需求,这里选取几个典型例子加以说明其用途所在之处及其重要性何在? 比如 CF 圆形 #701(Division Two)-Problem C(Floor And Mod), 这道题目要求我们找到满足特定条件的一系列数字组合方案数目统计工作当中需要用到大量的地板除法规律推导过程才能得出正确结论出来. 同样还有像CF Problem D(编号1469)-Ceiling Division Operations [^2], 此处探讨的就是怎样快速有效地把初始状态转变成为期望结束形态所经历过的最少次数动作规划策略研究方向上面去了.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值