Problem:
Score : 700 points

Problem Statement

N hotels are located on a straight line. The coordinate of the i-th hotel (1 \leq i \leq N) is x_i.

Tak the traveler has the following two personal principles:

He never travels a distance of more than L in a single day.

He never sleeps in the open. That is, he must stay at a hotel at the end of a day.

You are given Q queries. The j-th (1 \leq j \leq Q) query is described by two distinct integers a_j and b_j.
For each query, find the minimum number of days that Tak needs to travel from the a_j-th hotel to the b_j-th hotel following his principles.
It is guaranteed that he can always travel from the a_j-th hotel to the b_j-th hotel, in any given input.

Constraints

2 \leq N \leq 10^5

1 \leq L \leq 10^9

1 \leq Q \leq 10^5

1 \leq x_i < x_2 < ... < x_N \leq 10^9

x_{i+1} - x_i \leq L

1 \leq a_j,b_j \leq N

a_j \neq b_j

N,\,L,\,Q,\,x_i,\,a_j,\,b_j are integers.

Partial Score

200 points will be awarded for passing the test set satisfying N \leq 10^3 and Q \leq 10^3.

Input

The input is given from Standard Input in the following format:

N
x_1 x_2 ... x_N
L
Q
a_1 b_1
a_2 b_2
:
a_Q b_Q

Output

Print Q lines.
The j-th line (1 \leq j \leq Q) should contain the minimum number of days that Tak needs to travel from the a_j-th hotel to the b_j-th hotel.

Sample Input 1

9
1 3 6 13 15 18 19 29 31
10
4
1 8
7 3
6 7
8 5

Sample Output 1

4
2
1
2

For the 1-st query, he can travel from the 1-st hotel to the 8-th hotel in 4 days, as follows:

Day 1: Travel from the 1-st hotel to the 2-nd hotel. The distance traveled is 2.

Day 2: Travel from the 2-nd hotel to the 4-th hotel. The distance traveled is 10.

Day 3: Travel from the 4-th hotel to the 7-th hotel. The distance traveled is 6.

Day 4: Travel from the 7-th hotel to the 8-th hotel. The distance traveled is 10.

Solution in C# (Mono 4.6.2.0) (judge verdict: Runtime Error)

using System;

public class AtCoder
{
    public static void Main()
    {
        string[] s;
        s = NextS();
        int n = int.Parse(s[0]);
        s = NextS();
        int[] x = new int[n];
        for (int i = 0; i < n; i++) x[i] = int.Parse(s[i]);
        s = NextS();
        int d = int.Parse(s[0]);
        s = NextS();
        int q = int.Parse(s[0]);
        int[] a = new int[q];
        int[] b = new int[q];
        int tmp0, tmp1;
        for(int i=0; i<q; i++)
        {
            s = NextS();
            tmp0 = int.Parse(s[0]) - 1;
            tmp1 = int.Parse(s[1]) - 1;
            if (tmp0 < tmp1)
            {
                a[i] = tmp0;
                b[i] = tmp1;
            }
            else
            {
                a[i] = tmp1;
                b[i] = tmp0;
            }
        }

        int c = 0;
        int[] group = new int[n];
        bool[] hub = new bool[n];
        group[0] = 0;
        hub[0] = true;
        int tmp = x[0] + d;
        for(int i=1; i<n; i++)
        {
            if (x[i] < tmp)
            {
                group[i] = c;
            }
            else
            {
                c++;
                hub[i - 1] = true;
                group[i - 1] = c;
                group[i] = c;
                tmp = x[i - 1] + d;
            }
        }

        UnionFind uf = new UnionFind(n);
        int l = 0; int r = 0; int m = 0;      
        for (int i = 1; i < n; i++)
        {
            if (hub[i]) continue;
            tmp = x[i] + d;
            l = i;
            r = n;
            while (r - l > 1)
            {
                m = (l + r) / 2;
                if (x[m] > tmp) r = m;
                else l = m;
            }
            uf.par[i] = x[l];
        }

        for (int i = 0; i < q; i++)
        {
            if (group[a[i]] == group[b[i]])
            {
                Console.WriteLine(1);
                continue;
            }
            if (hub[b[i]])
            {                
                Console.WriteLine(group[b[i]] - group[a[i]]);
            }
            else
            {
                if (hub[a[i]])
                {
                    Console.WriteLine(group[b[i]] - group[a[i]] + 1);
                }
                else
                {
                    if(b[i] < uf.Find(a[i])) Console.WriteLine(group[b[i]] - group[a[i]]);
                    else Console.WriteLine(group[b[i]] - group[a[i]] + 1);
                }
            }            
        }
    }

    public static void DebugWL(object x) { System.Diagnostics.Debug.WriteLine(x); }
    public static string[] NextS() { return Console.ReadLine().Trim().Split(' '); }
}

// UnionFind(int n)
// n: the number of nodes
// int Find(int node): return the parent
// void Union(int node, int node)

public class UnionFind
{
    public int[] par;
    int n;
    public UnionFind(int t)
    {
        n = t;
        par = new int[n];
        for (int i = 0; i < n; i++)
        {
            par[i] = i;
        }
    }

    public int Find(int x)
    {
        if (par[x] == x) return x;
        else
        {
            par[x] = Find(par[x]);
            return par[x];
        }
    }

    public void Union(int x, int y)
    {
        x = Find(x);
        y = Find(y);
        if (x == y) return;
        else par[x] = y;
    }
}