二分
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
const int maxn = 1e5+100;
LL a[maxn];
int main(){
LL n, d;
while(scanf("%I64d%I64d", &n, &d) != EOF){
for(int i = 0; i < n; i++) scanf("%I64d", &a[i]);
LL ans = 0;
for(int i = 1; i < n; i++){
LL j = i - (lower_bound(a, a+i, a[i]-d)-a);
ans += (j-1)*j/2;
}
printf("%I64d\n", ans);
}
return 0;
}
尺取法
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
const int maxn = 1e5+100;
LL a[maxn];
int main(){
LL n, d;
while(scanf("%I64d%I64d", &n, &d) != EOF){
for(int i = 0; i < n; i++) scanf("%I64d", &a[i]);
LL ans = 0;
LL j = 0;
for(int i = 0; i < n; i++){
while(j < n && a[j] - a[i] <= d) j++;
ans += (j-i-1)*(j-i-2)/2;
}
printf("%I64d\n", ans);
}
return 0;
}
单调队列
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
const int maxn = 1e5+100;
LL a[maxn], que[maxn];
int main(){
LL n, d;
while(scanf("%I64d%I64d", &n, &d) != EOF){
for(int i = 0; i < n; i++) scanf("%I64d", &a[i]);
if(n < 3){ printf("0\n"); continue;}
LL ans = 0;
LL head = 0, tail = 0;
while(head <= tail){
while(a[tail] - a[head] <= d && tail < n) que[tail] = a[tail], tail++;
head++;
if(head < n) ans += (tail-head)*(tail-head-1)/2;
}
printf("%I64d\n", ans);
}
return 0;
}