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