1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll mod = 1e9+7;
const int N = 3e5+2;
int n;
ll a[N], r[N], w[N][2];
int l[N], mini[N];
int lowerbound(ll bound) {
	int lo = 1, hi = n, mid, res=n;
	while(lo<=hi) {
		mid=(lo+hi)/2;
		if(a[mid]>=bound) {
			res=mid;
			hi=mid-1;
		}
		else {
			lo=mid+1;
		}
	}
	return res;
}
int upperbound(ll bound) {
	int lo = 1, hi = n, mid, res=1;
	while(lo<=hi) {
		mid=(lo+hi)/2;
		if(a[mid]<=bound) {
			res=mid;
			lo=mid+1;
		}
		else {
			hi=mid-1;
		}
	}
	return res;
}
const int base = (1<<19);
int tree[2*base+1], mxtree[2*base+1], mintree[2*base+1];
void ins(int rl, int rr, int val) {
	if(rl>rr) return;
	rl+=base, rr+=base;
	tree[rl] = max(tree[rl], val), tree[rr] = max(tree[rr], val);
	while(rl/2 != rr/2) {
		if(rl%2==0) tree[rl+1] = max(tree[rl+1], val);
		if(rr%2==1) tree[rr-1] = max(tree[rr-1], val);
		rl/=2, rr/=2;
	}
}
int qry(int x) {
	x+=base;
	int res = 0;
	while(x) {
		res = max(res, tree[x]);
		x/=2;
	}
	return res;
}
int get_max(int rl, int rr) {
	rl+=base, rr+=base;
	int res = max(mxtree[rl], mxtree[rr]);
	while(rl/2!=rr/2) {
		if(rl%2==0) res = max(res, mxtree[rl+1]);
		if(rr%2==1) res = max(res, mxtree[rr-1]);
		rl/=2, rr/=2;
	}
	return res;
}
int get_min(int rl, int rr) {
	rl+=base, rr+=base;
	int res = min(mintree[rl], mintree[rr]);
	while(rl/2!=rr/2) {
		if(rl%2==0) res = min(res, mintree[rl+1]);
		if(rr%2==1) res = min(res, mintree[rr-1]);
		rl/=2, rr/=2;
	}
	return res;
}
void min_ins(int x, int val) {
	x+=base;
	while(x) {
		mintree[x] = min(mintree[x], val);
		x/=2;
	}
}
int main() {
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin>>n;
	for(int i=1; i<=n; ++i) {
		cin>>a[i]>>r[i];
	}
	for(int i=1; i<=n; ++i) {
		mxtree[i+base] = upperbound(a[i]+r[i]);
		mintree[i+base] = i;
	}
	for(int i=base-1; i>=1; --i) {
		mxtree[i] = max(mxtree[i*2], mxtree[i*2+1]);
		mintree[i] = min(mintree[i*2], mintree[i*2+1]);
	}
	w[0][0] = 1;
	for(int i=1; i<=n; ++i) {
		l[i] = qry(i);
		if(l[i]==0) l[i] = i;
		mini[i] = get_min(lowerbound(a[i]-r[i]), i);
		min_ins(i, mini[i]);
		w[i][0] = (w[i-1][0]+w[i-1][1]-w[l[i]][1]+mod)%mod;	
		w[i][1] = (w[mini[i]-1][0]+w[mini[i]-1][1])%mod;
		int mx = get_max(lowerbound(a[i]-r[i]), i);
		ins(i+1, mx, i);
	}
	
	cout<<(w[n][0]+w[n][1])%mod<<'\n';
}