题目链接:质区间长度 - 题目 - Daimayuan Online Judge
题意:
思路:首先分析题目,可以发现[x, x + len - 1], len越大,[x, x + len - 1]这个区间的质因数要么不变要么增加,不可能不出现减少的情况,因此它具有单调性,所以可以用二分答案来解决。二分的关键在于如何check这个方案是否合法,在这里我们即判断[x, x + mid -1](l<= x <= r-len+1)这些区间里面的质数数量是否都不小于k。在这里我们可以用线性筛预处理出一个前缀和数组sum[i],sum[i]表示区间[1, i]的质数数量,那么我们check这个区间[x, x + mid -1]是否合法即判断sum[x + mid - 1] - sum[x-1]是否不小于k即可,时间复杂度O(nlogn)
代码:
#include <bits/stdc++.h>
#define readI() read<int>()
#define readL() read<ll>()
#define ls u << 1
#define rs u << 1 | 1
#define lowbit(x) x & -x
#define pb push_back
using namespace std;
typedef pair<int, int> PII;
typedef long long ll;
const int N = 1e6 + 10;
int primes[N], cnt;
bool st[N];
int sum[N]; // 前缀和数组
template<typename T> inline T read()
{
T x = 0, f = 0;
char ch = getchar();
while (!isdigit(ch)) f |= ch=='-', ch = getchar();
while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
return f ? -x : x;
}
void init() // 预处理前缀和数组
{
int n = 1000000;
st[1] = true;
for (int i = 2; i <= n; i ++ ) {
if (!st[i]) primes[++cnt] = i, sum[i] = 1;
sum[i] += sum[i-1];
for (int j = 1; j <= cnt && i * primes[j] <= n; j ++ ) {
st[i * primes[j]] = true;
if (i % primes[j] == 0) break;
}
}
}
bool check(int len, int l, int r, int k)
{
for (int i = l + len - 1; i <= r; i ++ ) {
if (sum[i] - sum[i-len] < k) return false; // 方案不合法
}
return true;
}
void solve()
{
int L, R, k;
cin >> L >> R >> k;
init();
// 二分答案
int l = 1, r = R - L + 1;
while (l < r)
{
int mid = l + r >> 1;
if (check(mid, L, R, k)) r = mid;
else l = mid + 1;
}
if (!check(l, L, R, k)) puts("-1");
else cout << l;
}
int main()
{
int t = 1;
while (t -- ) solve();
return 0;
}
/*
1 1000000 0
*/