给出一个包括N个元素的整数数组A,包括A本身在内,共有 (N+1)*N / 2个非空子段。例如:1 3 2的子段为{1} {3} {2} {1 3} {3 2} {1 3 2}。在这些子段中,如果最大值同最小值的差异不超过K,则认为这是一个合格的子段。给出数组A和K,求有多少符合条件的子段。例如:3 5 7 6 3,K = 2,符合条件的子段包括:{3} {5} {7} {6} {3} {3 5} {5 7} {7 6} {5 7 6},共9个。
Input
第1行:2个数N, K(1 <= N <= 50000, 0 <= K <= 10^9) 第2 - N + 1行:每行1个数,对应数组的元素Ai(0 <= A[i] <= 10^9)
Output
输出符合条件的子段数量。
Input示例
5 2 3 5 7 6 2
Output示例
9
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define maxn 50005
using namespace std;
typedef long long ll;
int deq1[maxn], deq2[maxn];
int num[maxn];
ll f(int n){
return ((ll)n + 1) * n / 2;
}
int main(){
// freopen("in.txt", "r", stdin);
int n, k, l1 = 0, r1 = 0, l2 = 0, r2 = 0;
int pre = 0;
ll ans = 0, d = 0;
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; i++)
scanf("%d", num+i);
for(int i = 1; i <= n; i++){
while(l1 != r1 && num[deq1[r1-1]] < num[i])
r1--;
while(l2 != r2 && num[deq2[r2-1]] > num[i])
r2--;
deq1[r1++] = i;
deq2[r2++] = i;
if(abs(num[deq1[l1]] - num[deq2[l2]] > k)){
int maxs = max(deq1[l1], deq2[l2]) - 1;
ans += f(maxs - pre);
ans -= d;
int sign = -1;
while(l1 != r1 && num[deq1[l1]] - num[deq2[l2]] > k){
if(deq1[l1] > deq2[l2]){
l2++;
sign = 0;
}
else if(deq1[l1] < deq2[l2]){
l1++;
sign = 1;
}
}
int h1, h2;
if(sign == 0){
pre = h1 = deq2[l2-1];
h2 = deq1[l1];
}
else{
pre = h1 = deq1[l1-1];
h2 = deq2[l2];
}
d = f(h2 - h1 - 1);
}
}
ans += f(n - pre) - d;
printf("%I64d\n", ans);
return 0;
}