题解:CF487B Strip
Carey_chen · · 题解
这是一种双指针+ ST 表做法。
首先可以想到一个简单的
可以得到:
这个式子可以
还可以进一步优化,由于越往后分得的段数越多,
在同一序列中,
#include <bits/stdc++.h>
using namespace std;
int a[100010], dp[100010];
int Max[100010][30], Min[100010][30], nxt[100010][30];
int QMax(int l, int r) {...} // 求区间最大值
int QMin(int l, int r) {...} // 求区间最小值
int main()
{
int n, s, l;
scanf("%d %d %d", &n, &s, &l);
memset(Min, 0x3f, sizeof(Min));
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
Max[i][0] = a[i];
Min[i][0] = a[i];
nxt[i][0] = i + 1;
}
for(int j = 1; j <= 20; j++)
{
for(int i = 1; i <= n; i++)
{
nxt[i][j] = nxt[nxt[i][j-1]][j-1];
Max[i][j] = max(Max[i][j-1], Max[nxt[i][j-1]][j-1]);
Min[i][j] = min(Min[i][j-1], Min[nxt[i][j-1]][j-1]);
}
}
dp[0] = 0;
for(int i = 1, j = 0; i <= n; i++)
{
while(j + 1 < i && (QMax(j + 1, i) - QMin(j + 1, i) > s || dp[j] == 1e9))
{
j++;
}
if(i - j >= l)
{
dp[i] = dp[j] + 1;
}
else
{
dp[i] = 1e9;
}
}
printf("%d", dp[n] == 1e9 ? -1 : dp[n]);
return 0;
}