1 条题解
-
0
📝 题目大意
给定 (),求一个在 以上且不超过 的整数,使得它对 中的每一个数取模的结果都是 。
💡 解题思路
-
题目分析:题目要求找到一个数 ,使得 对所有 成立。等价于 能被 中的每一个数整除,即 是 的公倍数。最小的正整数 就是 。
-
算法推导:由于 ,我们可以直接迭代计算 到 的最小公倍数。设
ans为当前累计的 LCM,初始值ans = 2(对应 )。然后从 到 遍历,每次用公式 更新ans = lcm(ans, i)。最终输出ans + 1。为什么这样得到的答案一定满足 ?因为 时,$\mathrm{lcm}(2, 3, \ldots, 30) \approx 2.33 \times 10^{12}$,加 后仍远小于 ,题目保证答案存在。
-
边界与细节:
- 时,LCM 为 ,答案为 (),符合条件。
- 乘法时使用
1ll强制转为long long,避免int溢出。虽然 很小,但中间 LCM 会迅速增长到 级别,必须用 64 位整数。 - 使用
__gcd求最大公约数(GNU 内置函数),无需手写。
⏱️ 复杂度分析
- 时间复杂度:,其中 为过程中出现的最大数值。每次迭代做一次 运算, 的复杂度为 ,共 次迭代。
- 空间复杂度:,只使用了常数个变量。
💻 标准代码 (C++)
#include<bits/stdc++.h> using namespace std; #define ll long long // 快速读入整数 void read(ll& x){ char ch=getchar(); ll f=1;x=0; while(ch<'0'||ch>'9'){ if(ch=='-')f=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ x=x*10+ch-48; ch=getchar(); } x=x*f; } ll N; // 计算两个数的最小公倍数,注意 1ll 防止乘法溢出 ll lcm(ll A,ll B){ return A*1ll*B/__gcd(A,B); } int main(){ read(N); ll ans=2; // 初始 LCM = 2 // 从 3 到 N 迭代,累积计算 LCM(2, 3, ..., N) for(int i=3;i<=N;i++) ans=lcm(ans,i); cout<<ans+1; // 输出 LCM + 1 return 0; } -
- 1
信息
- ID
- 863
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者