Problem:
Score : 1100 points

Problem Statement

There is a set consisting of N distinct integers. The i-th smallest element in this set is S_i. We want to divide this set into two sets, X and Y, such that:

The absolute difference of any two distinct elements in X is A or greater.

The absolute difference of any two distinct elements in Y is B or greater.

How many ways are there to perform such division, modulo 10^9 + 7? Note that one of X and Y may be empty.

Constraints

All input values are integers.

1 ≦ N ≦ 10^5

1 ≦ A , B ≦ 10^{18}

0 ≦ S_i ≦ 10^{18}(1 ≦ i ≦ N)

S_i < S_{i+1}(1 ≦ i ≦ N - 1)

Input

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

N A B
S_1
:
S_N

Output

Print the number of the different divisions under the conditions, modulo 10^9 + 7.

Sample Input 1

5 3 7
1
3
6
9
12

Sample Output 1

5

There are five ways to perform division:

X={1,6,9,12}, Y={3}

X={1,6,9}, Y={3,12}

X={3,6,9,12}, Y={1}

X={3,6,9}, Y={1,12}

X={3,6,12}, Y={1,9}

Sample Input 2

7 5 3
0
2
4
7
8
11
15

Sample Output 2

4

Sample Input 3

8 2 9
3
4
5
13
15
22
26
32

Sample Output 3

13

Sample Input 4

3 3 4
5
6
7

Sample Output 4

0

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){
		
		var STA = new SegTree(N+1);
		var STB = new SegTree(N+1);
		
		STA.Update(0,1);
		
		for(int i=1;i<=N;i++){
			
			int l=0,r=N+1;
			int c=0;
			while(r-l>1){
				c = (l+r)/2;
				if(S[i] - S[c] >= B){
					l = c;
				}else{
					r = c;
				}
			}
			STB.Update(i,STA.QuerySum(0,c+1));
			
			l=0;r=N+1;
			c=0;
			while(r-l>1){
				c = (l+r)/2;
				if(S[i] - S[c] >= A){
					l = c;
				}else{
					r = c;
				}
			}
			STA.Update(i,STB.QuerySum(0,c+1));
			
			if(S[i-1] > S[i] - A){
				STA.QueryZero(0,i);
			}
			if(S[i-1] > S[i] - B){
				STB.QueryZero(0,i);
			}
		}
		
		long mod = (long)1e9 +  7;
		long ans = STA.QuerySum(0,N+1) + STB.QuerySum(0,N+1);
		ans %= mod;
		Console.WriteLine(ans);
		
	}
	int N;
	long A,B;
	long[] S;
	public Sol(){
		var d = rla();
		N = (int) d[0]; A = d[1]; B = d[2];
		S = new long[N+1];
		S[0] = -(long)3e18;
		for(int i=0;i<N;i++) S[i+1] = rl();
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}



class SegTree{
	//segment Tree 
	// 0-origin
	public int[] Data;	//実体
	public int Inf;	//初期化用のlargeNumber
	public int N;		//size 
	public int n;		//size (2の冪)
	int mod = (int)1e9 + 7;
	
	//コンストラクタ
	public SegTree(int n_,int inf_){
		N=n_;Inf=inf_;
		n=1;
		while(n<n_)n*=2;
		Data=new int[2*n-1];
		for(int i=0;i<2*n-1;i++)Data[i]=Inf;
	}
	public SegTree(int n_){
		N=n_;Inf=0;
		n=1;
		while(n<n_)n*=2;
		Data=new int[2*n-1];
		for(int i=0;i<2*n-1;i++)Data[i]=Inf;
	}
	
	//	   0
	//	 1   2
	//	3 4 5 6
	public void Update(int k,int a){
		k+=n-1;	//上にはn-1個乗る
		Data[k]=a;
		while(k>0){
			k=(k-1)/2;
			Data[k] = Data[k*2+1] + Data[k*2+2];
			if(Data[k] >= mod) Data[k] -= mod;
		}
	}
	
	public int QuerySum(int a,int b){
		return Query(a,b,0,0,n);
	}
	
	//RMQ;
	//	[a,b) のMinを返す
	//	後ろ3つの引数は	k,l,r：ヒープのk-ノードが範囲 [l,r) に対応していることを示す
	//	外から呼ぶ時は Query(a,b,0,0,n) の形で呼ぶ
	public int Query(int a,int b,int k,int l,int r){
		if(r<=a || b<=l) return Inf;
		if(a<=l && r<=b)return Data[k];
		int vl=Query(a,b,k*2+1,l,(l+r)/2);
		int vr=Query(a,b,k*2+2,(l+r)/2,r);
		int ret = vl + vr;
		if(ret >= mod) ret -= mod;
		return ret;
	}
	
	public void QueryZero(int a,int b){
		QueryZ(a,b,0,0,n);
	}
	public void QueryZ(int a,int b,int k,int l,int r){
		if(r<=a || b<=l) return ;
		if(a<=l && r<=b){Data[k] = 0; return;}
		QueryZ(a,b,k*2+1,l,(l+r)/2);
		QueryZ(a,b,k*2+2,(l+r)/2,r);
	}
	
	public void UniqInit(int val){
		for(int i=0+n-1;i<N+n-1;i++)Data[i]=val;
		int l=n-1;int r=N+n-1-1;
		while(l>0){
			l=(l-1)/2;r=(r-1)/2;
			for(int i=l;i<=r;i++)Data[i]=val;
		}
	}
	
	public void AddUpdate(int k,int a){
		//usage overflow注意
		Update(k,Data[k+n-1]+a);
	}
	
	public void Dump(){
		Console.WriteLine();
		int h=0;
		int cnt=0;
		for(int i=0;i<Data.Length;i++){
			Console.Write("{0} ",Data[i]);
			cnt++;
			if(cnt==1<<h){
				cnt=0;
				h++;
				Console.WriteLine();
			}
		}
	}
	
}