#include<bits/stdc++.h>
#define ll long long
using namespace std;
pair<ll, ll> mines[300009];
ll max_left[300009];
ll min_left[300009];
ll tree[(1 << 20) + 9];
ll dp[2][3000009];
const ll MOD = 1000000007;
struct node {
ll i;
ll max_right_range;
ll max_right_activation;
node(ll _i, ll _max_right_range, ll _max_right_activation) {
i = _i;
max_right_range = _max_right_range;
max_right_activation = _max_right_activation;
}
};
ll first(ll x){
ll p = 1;
ll q = x;
while(p < q){
ll m = (p + q) / 2;
if(mines[m].first < mines[x].first - mines[x].second)
p = m + 1;
else
q = m;
}
return p;
}
ll get_min(ll p, ll q) {
ll res = 1000000009;
p += (1 << 19) - 1;
q += (1 << 19) - 1;
while(p <= q and p > 0 and q > 0){
if(p % 2 == 1)
res = min(res, tree[p++]);
if(q % 2 == 0)
res = min(res, tree[q--]);
p /= 2;
q /= 2;
}
return res;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
ll n;
cin >> n;
for(ll i = 1; i <= n; i++) {
cin >> mines[i].first >> mines[i].second;
}
fill(tree, tree + (1 << 20) + 5, 1000000009);
for(ll i = 1; i <= n; i++){
ll begin = first(i);
max_left[i] = (begin == i ? i : get_min(begin, i));
ll v = i + (1 << 19) - 1;
tree[v] = max_left[i];
while(v > 1){
v /= 2;
tree[v] = min(tree[2 * v], tree[2 * v + 1]);
}
}
stack<node> min_left_stack;
min_left_stack.push(node(1, mines[1].first + mines[1].second, mines[1].first));
for(ll i = 2; i <= n; i++) {
while(not min_left_stack.empty() and min_left_stack.top().max_right_range < mines[i].first)
min_left_stack.pop();
if(not min_left_stack.empty()) {
min_left[i] = min_left_stack.top().i;
if((mines[i].first - mines[i].second) <= min_left_stack.top().max_right_activation) {
min_left_stack.top().i = i;
min_left_stack.top().max_right_range = max(min_left_stack.top().max_right_range, mines[i].first + mines[i].second);
min_left_stack.top().max_right_activation = mines[i].first;
}
}
min_left_stack.push(node(i, mines[i].first + mines[i].second, mines[i].first));
}
dp[0][1] = 1;
dp[1][1] = 1;
for(ll i = 2; i <= n; i++){
if(max_left[i] == 0)
dp[1][i] = 1;
if(max_left[i] > 0)
dp[1][i] = (dp[1][max_left[i] - 1] + dp[0][max_left[i] - 1]) % MOD;
dp[0][i] = (dp[0][i - 1] + dp[1][i - 1]) % MOD;
if(min_left[i] != 0)
dp[0][i] = (MOD + dp[0][i] - dp[1][min_left[i]]) % MOD;
}
cout << (dp[0][n] + dp[1][n]) % MOD << "\n";
return 0;
}
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 | #include<bits/stdc++.h> #define ll long long using namespace std; pair<ll, ll> mines[300009]; ll max_left[300009]; ll min_left[300009]; ll tree[(1 << 20) + 9]; ll dp[2][3000009]; const ll MOD = 1000000007; struct node { ll i; ll max_right_range; ll max_right_activation; node(ll _i, ll _max_right_range, ll _max_right_activation) { i = _i; max_right_range = _max_right_range; max_right_activation = _max_right_activation; } }; ll first(ll x){ ll p = 1; ll q = x; while(p < q){ ll m = (p + q) / 2; if(mines[m].first < mines[x].first - mines[x].second) p = m + 1; else q = m; } return p; } ll get_min(ll p, ll q) { ll res = 1000000009; p += (1 << 19) - 1; q += (1 << 19) - 1; while(p <= q and p > 0 and q > 0){ if(p % 2 == 1) res = min(res, tree[p++]); if(q % 2 == 0) res = min(res, tree[q--]); p /= 2; q /= 2; } return res; } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); ll n; cin >> n; for(ll i = 1; i <= n; i++) { cin >> mines[i].first >> mines[i].second; } fill(tree, tree + (1 << 20) + 5, 1000000009); for(ll i = 1; i <= n; i++){ ll begin = first(i); max_left[i] = (begin == i ? i : get_min(begin, i)); ll v = i + (1 << 19) - 1; tree[v] = max_left[i]; while(v > 1){ v /= 2; tree[v] = min(tree[2 * v], tree[2 * v + 1]); } } stack<node> min_left_stack; min_left_stack.push(node(1, mines[1].first + mines[1].second, mines[1].first)); for(ll i = 2; i <= n; i++) { while(not min_left_stack.empty() and min_left_stack.top().max_right_range < mines[i].first) min_left_stack.pop(); if(not min_left_stack.empty()) { min_left[i] = min_left_stack.top().i; if((mines[i].first - mines[i].second) <= min_left_stack.top().max_right_activation) { min_left_stack.top().i = i; min_left_stack.top().max_right_range = max(min_left_stack.top().max_right_range, mines[i].first + mines[i].second); min_left_stack.top().max_right_activation = mines[i].first; } } min_left_stack.push(node(i, mines[i].first + mines[i].second, mines[i].first)); } dp[0][1] = 1; dp[1][1] = 1; for(ll i = 2; i <= n; i++){ if(max_left[i] == 0) dp[1][i] = 1; if(max_left[i] > 0) dp[1][i] = (dp[1][max_left[i] - 1] + dp[0][max_left[i] - 1]) % MOD; dp[0][i] = (dp[0][i - 1] + dp[1][i - 1]) % MOD; if(min_left[i] != 0) dp[0][i] = (MOD + dp[0][i] - dp[1][min_left[i]]) % MOD; } cout << (dp[0][n] + dp[1][n]) % MOD << "\n"; return 0; } |
English