给一个正整数 \(n\) ,找一段最长的 \([l, r]\) ,满足 \(\forall i, i \in [l, r],\ s.t.\ i | n\) 。输出这一段区间的长度,即 \(r - l + 1\) 。
这题是一个准结论题,需要一些知识点和观察的基础。
放在 \(900\) 的位置是因为结论存在的区间太容易枚举出来了。
观察一:连续段整除问题,必然用到性质:
- 定理:连续 \(x\) 个数有且仅有在一个数被 \(x\) 整除。
- 证明:对于一段连续段 \([l, r]\) ,在 \(\mod (r - l + 1)\) 意义下,取遍所有余数 \([0, r - l]\) 。余数 \(0\) 存在且仅存在一个。
- 推论:对任意 \([l, r]\) ,若 \(\exists i, i \in [l, r]\) ,满足 \(\forall j, j \in [1, r - l + 1]\) ,有 \(j | i\) 。直接使用上述定理可以归纳证明。
观察二:当存在 \([l, r] | n\) ,则有 \([1, r - l + 1] | n\) 。则最长的 \([l, r] | n\) ,有最长的 \([1, r - l + 1] | n\) 。
于是问题可以求解。从 \(1\) 开始找连续的 \(x\) 满足 \(x | n\) ,\(x_{max}\) 即最长连续段整除 \(n\) 的段长。
view
#include <bits/stdc++.h>
typedef long long ll;
void solve() {
ll n; std::cin >> n;
for (int x = 1; ; x++) if (n % x != 0) { std::cout << x - 1 << '\n'; return; }
}
signed main() {
int _ = 1; std::cin >> _;
while (_--) { solve(); }
return 0;
}
- Codeforces Divisors Interval Longest Roundcodeforces divisors interval longest divisors interval longest 题解divisors interval longest performing interval longest 1124 约数 区间codeforces divisors educational codeforces round rated codeforces round 911 div codeforces round 864 div codeforces round 887 div codeforces round 863 div