题目大意:给你一串数字,问有几个连续的序其最大值与最小值之差不大于k。
借用双指针的思想,i,j初始化都为0,然后j往后移动,遇到第一个使区间不符合条件的位置停下,ans加上此时的区间数目,因为是连续的且以i为起点,所以区间只有j-i个;然后i往后移动,每移动一个位置,加一个j-i,直到与j那个位置有冲突的那一点,意思就是abs(a[j] - a[i]) > k的那一点,然后i再往后移动一位,继续移动j,直到结束
参考了一位学长的代码,用的multiset,set有自动排序的功能,就不用记录此时的最大值和最小值了,j移动一个点,就把那个点放入集合,如果符合条件,ans加上此时区间数目,如果最大值减去最小值大于等于k,就删去a[i],然后继续判断,知道小于k的那一点,然后加上此时的区间数目。
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <set>
#define maxn 100010
#define mod 1000000007
using namespace std;
int a[maxn];
int main(){
int t,n,k;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
for(int i = 0; i < n; i++)
scanf("%d",&a[i]);
multiset<int> st;
int i,j;
long long ans;
ans = 0;
for(i = 0, j = 0; i < n; i++)
{
st.insert(a[i]);
for(;*(st.rbegin()) - *(st.begin())>=k;j++)
st.erase(st.find(a[j]));
ans+=i-j+1;
}
printf("%lld\n",ans);
}
}