#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';
}
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'; } |
English