[CF237C Primes on Interval] 题解
来水一篇题解
由于这道题需要访问一个区间内的质数个数,所以我们可以先预处理,将质数线性筛出来,然后再前缀和一下,计算质数的数量。
由于答案满足“合法且最小”所以我们可以想到二分答案。check 的时候只需要使用尺取法 O ( n ) O(n) O(n) 遍历一下,对于每个长度为 l l l 的区间,计算质数的个数,并与 k k k 比较一下即可。
复杂度 T ( n ) = T ( n 2 ) + O ( n ) = O ( n log n ) \displaystyle T(n)=T(\frac{n}{2})+O(n)=O(n\log n) T(n)=T(2n)+O(n)=O(nlogn),可以通过本题。
int prime[1000010];
void ethra() {
prime[0] = 0;
prime[1] = 1;
for (int i = 2; i <= 1000000; i++)
if (!prime[i])
for (int j = i + i; j <= 1000000; j += i)
prime[j] = 1;
for (int i = 1; i <= 1000000; i++)
prime[i] = prime[i - 1] + !prime[i];
}
int k;
int a, b;
bool check(int l) {
for (int i = a + l - 1; i <= b; i++)
if (prime[i] - prime[i - l] < k)
return false;
return true;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
ethra();
cin >> a >> b >> k;
int l = 0, r = b - a + 1;
while (l < r) {
int mid = (l + r) >> 1;
if (check(mid, a, b))
r = mid;
else
l = mid + 1;
}
if (l == b - a + 1) {
if (check(l, a, b))
cout << l << endl;
else
cout << "-1\n";
}
else
cout << l << endl;
return 0;
}