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 Java8 (OpenJDK 1.8.0) (judge verdict: Time Limit Exceeded)


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Queue;

/**
 * Created by jaga on 9/7/16.
 * 貪欲法で調べていく。が、全地点に関してそれをやると部分点解法だと思われる
 * dpで、ある地点からある地点にかかる日数を調べておく
 * dp[j][k] = j番目の地点からk番目の地点にかかる日数 INFで初期化 j <= k
 * dp[j][k] = Min(dp[j][k-1], dp[j][k-2], ,,, dp[j][k -10]) + 1;
 * 距離がLまでの以前の地点のうち、もっとも日数がかからない地点に+1した値
 * 貪欲法で考えるなら一番遠くの値
 * ただし、k - x >=j に注意しておく
 * これだとループを回す回数は 最大N ^ 2のオーダー
 * <p>
 * MLEでた。dp[j][k]とdp[j-1][k]は全く関係ないので、底を考慮
 */
public class Main {
    public static void main(String args[]) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(System.out);

        int N, L, Q;
        int INF = 100000000;
        int x[];


        String line = br.readLine();
        N = Integer.parseInt(line);

        line = br.readLine();
        String text[] = line.split(" ");
        x = new int[N];
        for (int i = 0; i < N; i++) {
            x[i] = Integer.parseInt(text[i]);
        }

        ArrayList<Integer> q[] = new ArrayList[N];

        line = br.readLine();
        L = Integer.parseInt(line);

        line = br.readLine();
        Q = Integer.parseInt(line);

        Node sum[] = new Node[Q];
        ArrayList<Node> idx[] = new ArrayList[N];

        for (int i = 0; i < N; i++) {
            idx[i] = new ArrayList<Node>();
        }

        int aa, bb, min, max;
        for (int i = 0; i < Q; i++) {
            line = br.readLine();
            text = line.split(" ");
            aa = Integer.parseInt(text[0]) - 1;
            bb = Integer.parseInt(text[1]) - 1;
            min = Math.min(aa, bb);
            max = Math.max(aa, bb);
            sum[i] = new Node(min, max);
            idx[min].add(sum[i]);
        }

        int dp[] = new int[N];

        //現在使用できる最も遠い地点を保管する
        PriorityQueue<Integer> que = new PriorityQueue<Integer>();

        loop:
        for (int i = 0; i < N; i++) {
            if (idx[i].isEmpty()) continue;
            //出発点の座標
            int from = x[i];
            que.clear();
            que.add(i);

            //dpの初期化
            Arrays.fill(dp, INF);
            dp[i] = 0;

            for (int k = i + 1; k < N; k++) {
                int to = x[k];

                while (true) {
                    //一番遠い地点がL圏内にくるまでpoll
                    if (to - x[que.peek()] > L) {
                        que.poll();
                    } else {
                        break;
                    }
                }
                if (que.isEmpty()) System.out.println("error");
                dp[k] = dp[que.peek()] + 1;
                que.add(k);
            }
            for (Node nd : idx[i]) {
                int k = nd.to;
                nd.dis = dp[k];
            }
        }
        for (int i = 0; i < Q; i++) {
            out.println(sum[i].dis);
        }
        out.flush();
    }
}

class Node {
    int from, to, dis; //dis = distance

    Node(int from, int to) {

        this.from = from;
        this.to = to;
    }
}