大体题意:
给你n 个数,要求选择一个区间l,r 使得 l~r 之间的数a[i] 满足 a[l] < a[i] < a[r] 求最大的r-l?
思路:
rmq+预处理!
我们可以枚举区间的左端点l,我们需要找到左端点l 的右方第一个小于等于a[l]的位置k,然后我们求出 l ~ k-1区间内的最大值a[pos],如果最大值大于a[l],那么 pos - l 就是答案之一,更新一下最大值即可!
那么问题来了:
rmq求的是 区间内的最大值,但是我们这个题目不仅要求出最大值,还要求出最大值所在的位置!
其实也很好解决,稍微改动一下rmq 即可! 我们让rmq 中的dp[i][j] 记录的是 第i 个位置开始 长度为(1<<j) 的最大值所在位置,这样两个问题就都解决了,注意 如果rmq中两个区间 左边的最大值和右边的最大值相等的话要记录左端点的最大值,否则右边最大值会和左边最大值冲突,解不合法!
然后就是如何求出每一个位置 的右方第一个小于等于他的位置?
我们开一个数组预处理,令r[i]为第i 个位置右方第一个小于等于a[i]的位置! 为了方便,我们可以在原始数据的末尾在加一个-inf 无限小!
那么如果a[i] >= a[i+1]直接r[i] = i + 1;
否则就让他一直往后跳,跳到头为止!
详细见代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 50000 + 7;
const int inf = 0x3f3f3f3f;
int a[maxn];
int dp[maxn][20], n, r[maxn];
void rmq(){
for (int i = 0; i < n; ++i) dp[i][0] = i;
for (int j = 1; (1 << j) <= n; ++j){
for (int i = 0; i + (1 << j) - 1 < n; ++i){
int t1 = dp[i][j-1];
int t2 = dp[i+(1<<(j-1))][j-1];
if (a[t1] >= a[t2]) dp[i][j] = t1;
else dp[i][j] = t2;
}
}
}
int query(int l,int r){
int k = 0;
while((1 << (k+1) ) <= r-l + 1)++k;
int t1 = dp[l][k];
int t2 = dp[r-(1<<k)+1][k];
if (a[t1] >= a[t2]) return t1;
return t2;
}
int main(){
while(scanf("%d",&n) == 1){
for (int i = 0; i < n; ++i){
scanf("%d",&a[i]);
}
rmq();
a[n] = -inf;
r[n-1] = n;
for (int i = n-2; ~i; --i){
if (a[i] >= a[i+1]) r[i] = i+1;
else{
int cur = i+1;
while(1){
if (a[cur] <= a[i]){
r[i] = cur;
break;
}
cur = r[cur];
}
}
}
int ans = 0;
for (int i = 0; i < n; ++i){
int id = query(i,r[i]-1);
if (a[id] > a[i]) ans = max(ans,id-i);
}
if (!ans)printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}
Time Limit: 6000MS | Memory Limit: 65536K | |
Total Submissions: 10430 | Accepted: 2771 |
Description
Now given the length of S1, S2, S3, …Sn, you are required to find the maximum value j - i.
Input
Line 1: a single integer n (n <= 50000), indicating the number of sticks.
Line 2: n different positive integers (not larger than 100000), indicating the length of each stick in order.
Output
Sample Input
4 5 4 3 6 4 6 5 4 3
Sample Output
1 -1
Source