#include <bits/stdc++.h> using namespace std; typedef pair<int,int> pii; const int MX=540540,md=1000000007; struct Node { int dp,sum,rgh; bool ok; } seg[MX*2]; int n,i,j,res,rgh,lft[MX]; long long a[MX],d[MX]; vector<int> r[MX]; set<pii> prs; set<int> e; int findmax(int i, int L, int R, int le, int ri) { if (L==le && R==ri) return seg[i].rgh; int h=(L+R)/2,mx=0; if (le<=h) mx=max(mx,findmax(i*2,L,h,le,min(h,ri))); if (ri>h) mx=max(mx,findmax(i*2+1,h+1,R,max(h+1,le),ri)); return mx; } int findsum(int i, int L, int R, int le, int ri) { if (L==le && R==ri) return seg[i].sum; int h=(L+R)/2,sum=0; if (le<=h) sum=findsum(i*2,L,h,le,min(h,ri)); if (ri>h) { sum+=findsum(i*2+1,h+1,R,max(h+1,le),ri); if (sum>=md) sum-=md; } return sum; } void mdfrgh(int i, int L, int R, int pos, int v) { if (L==R) { seg[i].rgh=v; return; } int h=(L+R)/2; if (pos<=h) mdfrgh(i*2,L,h,pos,v); else mdfrgh(i*2+1,h+1,R,pos,v); seg[i].rgh=max(seg[i*2].rgh,seg[i*2+1].rgh); } void mdfdp(int i, int L, int R, int pos, int v) { if (L==R) { seg[i].dp=v; seg[i].sum=(seg[i].ok?v:0); return; } int h=(L+R)/2; if (pos<=h) mdfdp(i*2,L,h,pos,v); else mdfdp(i*2+1,h+1,R,pos,v); seg[i].sum=seg[i*2].sum+seg[i*2+1].sum; if (seg[i].sum>=md) seg[i].sum-=md; } void mdfok(int i, int L, int R, int pos) { if (L==R) { seg[i].ok=!seg[i].ok; seg[i].sum=(seg[i].ok?seg[i].dp:0); return; } int h=(L+R)/2; if (pos<=h) mdfok(i*2,L,h,pos); else mdfok(i*2+1,h+1,R,pos); seg[i].sum=seg[i*2].sum+seg[i*2+1].sum; if (seg[i].sum>=md) seg[i].sum-=md; } void add(int idx) { pii p={idx,lft[idx]},q={idx,0}; auto it=prs.upper_bound(q); while (it!=prs.begin()) { --it; if (it->first>=p.second) { p.second=min(p.second,it->second); mdfok(1,0,n-1,it->second); prs.erase(it); } else break; it=prs.upper_bound(q); } it=prs.upper_bound(q); while (it!=prs.end()) { if (p.first>=it->second) { p.first=max(p.first,it->first); mdfok(1,0,n-1,it->second); prs.erase(it); } else break; it=prs.upper_bound(q); } mdfok(1,0,n-1,p.second); prs.insert(p); } int main() { scanf("%d",&n); for (i=0; i<n; i++) scanf("%lld%lld",&a[i],&d[i]); res=1; mdfdp(1,0,n-1,0,1); mdfdp(1,0,n-1,1,1); for (i=0; i<n; i++) { for (auto idx: r[i]) { e.erase(idx); add(idx); } lft[i]=lower_bound(a,a+n,a[i]-d[i])-a; rgh=upper_bound(a,a+n,a[i]+d[i])-a-1; rgh=max(rgh,(lft[i]==i)?i:findmax(1,0,n-1,lft[i],i-1)); if (rgh<=i) { add(i); if (!e.empty()) { auto it=e.end(); --it; j=(*it)+1; } else j=0; res+=findsum(1,0,n-1,j,i); if (res>=md) res-=md; } else { e.insert(i); r[rgh].push_back(i); mdfrgh(1,0,n-1,i,rgh); } if (i+2<n) mdfdp(1,0,n-1,i+2,res); } printf("%d\n",res); 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 110 111 112 113 114 115 116 117 118 | #include <bits/stdc++.h> using namespace std; typedef pair<int,int> pii; const int MX=540540,md=1000000007; struct Node { int dp,sum,rgh; bool ok; } seg[MX*2]; int n,i,j,res,rgh,lft[MX]; long long a[MX],d[MX]; vector<int> r[MX]; set<pii> prs; set<int> e; int findmax(int i, int L, int R, int le, int ri) { if (L==le && R==ri) return seg[i].rgh; int h=(L+R)/2,mx=0; if (le<=h) mx=max(mx,findmax(i*2,L,h,le,min(h,ri))); if (ri>h) mx=max(mx,findmax(i*2+1,h+1,R,max(h+1,le),ri)); return mx; } int findsum(int i, int L, int R, int le, int ri) { if (L==le && R==ri) return seg[i].sum; int h=(L+R)/2,sum=0; if (le<=h) sum=findsum(i*2,L,h,le,min(h,ri)); if (ri>h) { sum+=findsum(i*2+1,h+1,R,max(h+1,le),ri); if (sum>=md) sum-=md; } return sum; } void mdfrgh(int i, int L, int R, int pos, int v) { if (L==R) { seg[i].rgh=v; return; } int h=(L+R)/2; if (pos<=h) mdfrgh(i*2,L,h,pos,v); else mdfrgh(i*2+1,h+1,R,pos,v); seg[i].rgh=max(seg[i*2].rgh,seg[i*2+1].rgh); } void mdfdp(int i, int L, int R, int pos, int v) { if (L==R) { seg[i].dp=v; seg[i].sum=(seg[i].ok?v:0); return; } int h=(L+R)/2; if (pos<=h) mdfdp(i*2,L,h,pos,v); else mdfdp(i*2+1,h+1,R,pos,v); seg[i].sum=seg[i*2].sum+seg[i*2+1].sum; if (seg[i].sum>=md) seg[i].sum-=md; } void mdfok(int i, int L, int R, int pos) { if (L==R) { seg[i].ok=!seg[i].ok; seg[i].sum=(seg[i].ok?seg[i].dp:0); return; } int h=(L+R)/2; if (pos<=h) mdfok(i*2,L,h,pos); else mdfok(i*2+1,h+1,R,pos); seg[i].sum=seg[i*2].sum+seg[i*2+1].sum; if (seg[i].sum>=md) seg[i].sum-=md; } void add(int idx) { pii p={idx,lft[idx]},q={idx,0}; auto it=prs.upper_bound(q); while (it!=prs.begin()) { --it; if (it->first>=p.second) { p.second=min(p.second,it->second); mdfok(1,0,n-1,it->second); prs.erase(it); } else break; it=prs.upper_bound(q); } it=prs.upper_bound(q); while (it!=prs.end()) { if (p.first>=it->second) { p.first=max(p.first,it->first); mdfok(1,0,n-1,it->second); prs.erase(it); } else break; it=prs.upper_bound(q); } mdfok(1,0,n-1,p.second); prs.insert(p); } int main() { scanf("%d",&n); for (i=0; i<n; i++) scanf("%lld%lld",&a[i],&d[i]); res=1; mdfdp(1,0,n-1,0,1); mdfdp(1,0,n-1,1,1); for (i=0; i<n; i++) { for (auto idx: r[i]) { e.erase(idx); add(idx); } lft[i]=lower_bound(a,a+n,a[i]-d[i])-a; rgh=upper_bound(a,a+n,a[i]+d[i])-a-1; rgh=max(rgh,(lft[i]==i)?i:findmax(1,0,n-1,lft[i],i-1)); if (rgh<=i) { add(i); if (!e.empty()) { auto it=e.end(); --it; j=(*it)+1; } else j=0; res+=findsum(1,0,n-1,j,i); if (res>=md) res-=md; } else { e.insert(i); r[rgh].push_back(i); mdfrgh(1,0,n-1,i,rgh); } if (i+2<n) mdfdp(1,0,n-1,i+2,res); } printf("%d\n",res); return 0; } |