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