Description
算出一个序列有多少个区间。满足最大值-最小值< k
Input
第一行为用例组数t,每组用例第一行为序列长度n,第二行为n个整数表示这个序列
Output
对于每组用例,输出满足条件的区间个数
Sample Input
2
4 2
3 1 2 4
10 5
0 3 4 5 2 1 6 7 8 9
Sample Output
5
28
Solution
multiset储存合格集合,每次新加入的数与最大值和最小值比较
Code
#include<cstdio>
#include<iostream>
#include<set>
#include<algorithm>
using namespace std;
#define maxn 111111
int n,k,a[maxn],mmin,mmax;
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n>>k;
for(int i=0;i<n;i++)
cin>>a[i];
if(!k)
{
printf("0\n");
continue;
}
multiset<int>s;
s.insert(a[0]);
int l=0,r=1;
long long ans=0;
while(1)
{
if(s.size())//集合非空
{
mmin=*s.begin();//集合最小值
mmax=*s.rbegin();//集合最大值
if(abs(a[r]-mmin)<k&&abs(a[r]-mmax)<k)//如果满足条件
{
ans+=(long long)s.size();//累加答案
s.insert(a[r]);//将其加入集合
r++;//右标右移
if(r==n)
break;
}
else
{
if(s.size())//删点
s.erase(s.find(a[l]));
l++;//左标右移
}
}
else//空集合
{
l=r;//更新左标值
s.insert(a[r]);//将点加入集合
r++;//右标右移
if(r==n)
break;
}
}
printf("%lld\n",ans+n);//注意每个数本身也可以作为一个满足条件的集合
}
return 0;
}