题目大意:给你一个长度为n的序列a(1<=n<=27000,1<=a[i]<=1e9),m(1<=m<=27000)个查询,k(1<=k<=1e9),每次查询给出li,ri。需要回答在[li,ri]这个区间内有多少对(i,j)满足i<j并且a[i]-a[j]<=k。

思路:题目没有要求在线做,并且又是这么多的区间询问,再看数据范围,显然可以用莫队做。因为莫队算法本身就是每次维护区间的边缘+1或者-1。所以对于一个区间,往最左边或最右边新加入一个数x,那么答案就会多出原来区间里数值大小在[x-k,x+k]范围的个数个。减少一个数同理。然后我们就可以用树状数组来维护个数。因为数值较大需要离散化。
AC代码:

//#include<bits/stdc++.h>
#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<ctime>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
#define pb push_back
#define X first
#define Y second
inline ll gcd(ll a, ll b) { while (b != 0) { ll c = a % b; a = b; b = c; }return a < 0 ? -a : a; }
inline ll lcm(ll a, ll b) { return (a * b) / gcd(a, b); }
inline ll lowbit(ll x) { return x & (-x); }
const double PI = 3.14159265358979323846;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
inline char nc() {
    static char buf[1 << 21], * p1 = buf, * p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
inline ll rd() {
    //#define getchar nc
    ll x = 0, f = 1; char ch = getchar();
    while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar(); }
    return x * f;
}
const double eps = 1e-6;
const int M = 1e6 + 10;
const int N = 1e5 + 10;
int a[N];
int n, m, k;
int maxx;
vector<int>v;
int b[N];
void discreat() {
    for (int i = 1; i <= n; i++)v.pb(a[i]);
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
    maxx = v.size();
    for (int i = 1; i <= maxx; i++)b[i] = v[i - 1];
}
inline int getid(int x) {
    return lower_bound(b + 1, b + 1 + maxx, x) - b;
}
int nl, nr;
ll now;
int S;
struct MM {
    int id, l, r, bk;
    bool friend operator<(const MM& m1, const MM& m2) {
        if (m1.bk != m2.bk)return m1.bk < m2.bk;
        return m1.r < m2.r;
    }
}qr[N];

int c[N];
inline void update(int x, int y) {
    for (; x <= maxx; x += lowbit(x)) {
        c[x] += y;
    }
}
inline int query_sum(int x) {
    int sum = 0;
    for (; x > 0; x -= lowbit(x)) {
        sum += c[x];
    }
    return sum;
}
int L[N], R[N];
inline int get(int x) {
    if (L[x] > R[x])return 0;
    return query_sum(R[x]) - query_sum(L[x] - 1);
}
int has[N];
inline void add(int x) {
    now += 1ll * get(x);
    update(has[x], 1);
}
inline void del(int x) {
    update(has[x], -1);
    now -= 1ll * get(x);
}
inline void move(int tl, int tr) {
    while (nr < tr)add(++nr);
    while (nl > tl)add(--nl);
    while (nr > tr)del(nr--);
    while (nl < tl)del(nl++);
}
ll ans[N];
int main() {
    n = rd(), m = rd(), k = rd();
    for (int i = 1; i <= n; i++)a[i] = rd();
    S = n / sqrt(m);
    discreat();
    for (int i = 1; i <= n; i++)has[i] = getid(a[i]);
    for (int i = 1; i <= n; i++) {
        L[i] = lower_bound(b + 1, b + 1 + maxx, a[i] - k) - b;
        R[i] = lower_bound(b + 1, b + 1 + maxx, a[i] + k) - b;
        if (R[i] == maxx + 1 || b[R[i]] > a[i] + k)R[i]--;
    }
    for (int i = 1; i <= m; i++) {
        qr[i].l = rd(), qr[i].r = rd();
        qr[i].id = i;
        qr[i].bk = (qr[i].l - 1) / S;
    }
    sort(qr + 1, qr + 1 + m);
    nl = 1, nr = 0, now = 0;
    for (int i = 1; i <= m; i++) {
        move(qr[i].l, qr[i].r);
        ans[qr[i].id] = now;
    }
    for (int i = 1; i <= m; i++)printf("%lld\n", ans[i]);
}