Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Escape from the Hell

One day, Buddha looked into the hell and found an office worker. He did evil, such as enforcing hard work on his subordinates. However, he made only one good in his life. He refused an unreasonable request from his customer to save the lives of his subordinates. Buddha thought that, as the reward of the good, the office worker should have had a chance to escape from the hell. Buddha took a spider silk and put down to the hell.

The office worker climbed up with the spider silk, however the length of the way $L$ meters was too long to escape one day. He had $N$ energy drinks and drunk one of them each day. The day he drunk the i-th energy drink he could climb $A_i$ meters in the daytime and after that slided down $B_i$ meters in the night. If he could reach at the height greater than or equal to the $L$ meters in the daytime, he could escape without sliding down. After the $N$ days the silk would be cut.

He realized that other sinners climbed the silk in the night. They climbed $C_i$ meters in the $i$-th night without sliding down in the daytime. If they catched up with the office worker, they should have conflicted and the silk would be cut. Therefore he needed to escape before other sinners catched him. Your task is to write a program computing the best order of energy drink and output the earliest day which he could escape. If he could not escape, your program should output -1.

Input

The input consists of a single test case.

$N$ $L$

$A_1$ $B_1$

$A_2$ $B_2$

...

$A_N$ $B_N$

$C_1$

$C_2$

...

$C_N$

The first line contains two integers $N$ ($1 \leq N \leq 10^5$) and $L$ ($1 \leq L \leq 10^9$), which mean the number of energy drinks and the length of the spider silk respectively. The following $N$ lines show the information of the drinks: the $i$-th of them indicates the $i$-th energy drink, he climbed up $A_i$ ($1 \leq A_i \leq 10^9$) meters and slided down $B_i$ ($1 \leq B_i \leq 10^9$) meters. Next $N$ lines show how far other sinners climbed: the $i$-th of them contains an integer $C_i$ ($1 \leq C_i \leq 10^9$), which means they climbed up $C_i$ meters in the $i$-th day.

Output

Print the earliest day which he could escape. If he could not escape, print -1 instead.

Sample Input 1

3 9
6 3
5 2
3 1
2
2
2

Output for the Sample Input 1

2

Sample Input 2

5 20
3 2
4 2
6 3
8 4
10 5
4
2
3
4
5

Output for the Sample Input 2

-1

Sample Input 3

5 20
6 5
7 3
10 3
10 14
4 7
2
5
3
9
2

Output for the Sample Input 3

3

Sample Input 4

4 12
8 4
6 4
2 1
2 1
1
1
4
4

Output for the Sample Input 4

-1

Solution in C++ (judge verdict: Time Limit Exceeded)

#include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM -2000000000
#define SIZE 100000

struct Info{
	Info(ll arg_A,ll arg_B){
		A = arg_A;
		B = arg_B;
	}
	bool operator<(const struct Info& arg) const{ //A-Bの降順
		return A-B > arg.A-arg.B;
	}
	ll A,B;
};

int N;
ll* table;
ll enemy[SIZE],self[SIZE],max_A[SIZE];
vector<Info> info;

//簡易化のため、要素数を2のべき乗にする関数
void init(int first_N){
	while(N < first_N)N *= 2;
}

void update(int loc,ll value){
	loc += N-1;

	table[loc] = value;

	if(N == 1)return;

	int parent = (loc-1)/2;

	while(true){
		table[parent] = max(table[2*parent+1],table[2*parent+2]); //親は左右の子の大きい方の値を持つ

		if(parent == 0)break;
		else{
			parent = (parent-1)/2;
		}
	}
}


//任意の区間の最大値を求める関数
ll query(int search_left,int search_right,int node_id,int node_left,int node_right){

	//今回のノードが検索区間をカバーしていなければ、結果に関係ない値を返す
	if(search_right < node_left || search_left > node_right)return NUM;

	//今回のノードの区間が、検索区間の部分区間である場合、今回のノードの値を返す
	if(search_left <= node_left && search_right >= node_right){
		return table[node_id];
	}

	//今回のノードの区間に、一部検索区間と重なっている区間がある場合→再帰的に子どもに尋ねる
	ll left_max= query(search_left,search_right,2*node_id+1,node_left,(node_left+node_right)/2);
	ll right_max = query(search_left,search_right,2*node_id+2,(node_left+node_right)/2+1,node_right);

	return max(left_max,right_max);
}

int main(){

	int first_N;
	ll L;

	scanf("%d %lld",&first_N,&L);

	ll A,B;
	for(int i = 0; i < first_N; i++){
		scanf("%lld %lld",&A,&B);
		info.push_back(Info(A,B));
	}

	//敵の高さを計算
	for(int i = 0; i < first_N; i++){
		scanf("%lld",&enemy[i]);
		if(i != 0){
			enemy[i] += enemy[i-1]; //累積和を計算
		}
	}

	sort(info.begin(),info.end());

	//自分の高さを計算
	for(int i = 0; i < first_N; i++){
		self[i] = info[i].A-info[i].B;
		if(i != 0){
			self[i] += self[i-1];
		}
	}
	//ある日を含め、ある日より右にある、最大のAを求める
	max_A[first_N-1] = info[first_N-1].A;
	for(int i = first_N-2; i >= 0; i--){
		max_A[i] = max(max_A[i+1],info[i].A);
	}

	//Bをセグメント木に登録する
	N = 1;
	init(first_N);

	table = new ll[2*N-1];

	//0～N-2が上位構造のアドレス、N-1～2*N-2が最小要素のアドレス
	for(int i = 0; i <= 2*N-2; i++)table[i] = NUM;  //まずは範囲外値で初期化
	//Bを登録
	for(int i = 0; i < first_N; i++){
		update(i,info[i].B);
	}

	int ans = BIG_NUM;
	int limit;

	ll tmp_H;
	/*★A-Bの降順に値を採用、脱出日は最大のAを使用する場合★*/

	//初日で脱出可
	if(max_A[0] >= L){
		printf("1\n");
		return 0;
	}

	for(int i = 1; i < first_N; i++){

		if(self[i-1] <= enemy[i-1]){ //敵に追いつかれたので終了
			limit = i;
			break;
		}
		tmp_H = self[i-1]+max_A[i];

		if(tmp_H >= L){
			ans = i+1; //解答は1オリジンのため
			break;
		}
	}

	bool FLG;

	/*★脱出日までの、どこか一日を、最終日に持ってくる場合★*/
	int left = 0,right,m;
	int min_index;
	ll max_B;

	for(int i = 1; i < first_N; i++){

		if(self[i-1] <= enemy[i-1]){ //敵に追いつかれたので終了
			break;
		}
		//0～i日目の間で、i日目に順番を回しても、敵に追いつかれないドリンクの範囲を二分探索で求める
		right = i,m = (left+right)/2; //★始点は随時右にずれていくので、初期化せずに値を引き継ぐ

		min_index = BIG_NUM;

		while(left <= right){

			FLG = true;
			//ドリンクmを飲むのをi日目にすることで、敵に追いつかれるか調べる
			for(int k = m+1; k <= i; k++){
				if(self[k]-enemy[k-1] <= info[m].A-info[m].B){ //自分が抜けた翌日以降の敵との差が、自分の加算分以下ならout(追いつかれる)
					FLG = false;
					break;
				}
			}
			if(FLG){

				min_index = m;
				right = m-1;

			}else{
				left = m+1;
			}
			m = (left+right)/2;
		}

		if(min_index == BIG_NUM)continue;

		max_B = query(min_index,i,0,0,N-1); //★i日に回しても良いドリンクの中での、Bの最大値を取得★

		tmp_H = self[i]+max_B; //★★加算していたマイナスが消える分(マイナスのマイナス)、プラスになる

		if(tmp_H >= L){
			ans = min(ans,i+1);
			break;
		}
	}

	if(ans == BIG_NUM){
		printf("-1\n");
	}else{
		printf("%d\n",ans);
	}

	return 0;
}