#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 10010, INF = 100000000;
int n;
int a[N];
int main()
{
cin >> n;
for (int i = 0; i < n; i ++ ) cin >> a[i];
int res = 0;
for (int i = 0; i < n; i ++ ) // 枚举区间左端点
{
int minv = INF, maxv = -INF;
for (int j = i; j < n; j ++ ) // 枚举区间右端点
{
minv = min(minv, a[j]);
maxv = max(maxv, a[j]);
if (maxv - minv == j - i) res ++ ;
}
}
cout << res << endl;
return 0;
}
maxv和minv是用来记录当前枚举区间[i,j]中的最大值和最小值的变量。在每次枚举j时,都会更新maxv和minv,以保证它们分别记录的是当前区间[i,j]中的最大值和最小值。这样,就可以在O(1)的时间内计算出当前区间的最大值和最小值。
这段代码是在求一个数组中所有子数组中,元素的最大值和最小值之差等于子数组长度的子数组个数。
if (maxv - minv == j - i)这个if语句的作用是判断当前子数组是否符合条件,即元素的最大值和最小值之差等于子数组长度。如果符合条件,就将结果res加1。
其中,maxv表示当前子数组中的最大值,minv表示当前子数组中的最小值,j表示当前子数组的右端点,i表示当前子数组的左端点。因为是枚举所有子数组,所以i和j的循环都是从0到n-1。
举个例子,假设当前子数组为[3, 1, 2, 4, 5],则maxv为5,minv为1,j-i为4,maxv-minv为4,符合条件,结果res加1。
需要注意的是,由于数组中可能存在负数,因此在初始化最大值和最小值时,需要将它们分别赋值为负无穷和正无穷,以确保能够正确计算。