#include <bits/stdc++.h> using namespace std; #define rep(i,a,n) for (int i=a;i<n;i++) #define per(i,a,n) for (int i=n-1;i>=a;i--) #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define fi first #define se second #define SZ(x) ((int)(x).size()) typedef vector<int> VI; typedef long long ll; typedef pair<int,int> PII; typedef double db; //mt19937 mrand(random_device{}()); const ll mod=1000000007; //int rnd(int x) { return mrand() % x;} ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} int gcd(int a,int b) { return b?gcd(b,a%b):a;} // head const int N=4e5+5; #define INF 0x3f3f3f3f template<class T> inline void read(T &x) { x=0; int c=getchar(),f=1; for (;!isdigit(c);c=getchar()) if (c==45) f=-1; for (;isdigit(c);c=getchar()) (x*=10)+=f*(c-'0'); } int n,nr,dp[N],s[N],SCC[N],deg[N]; ll a[N],r[N]; VI e[N],et[N]; bool vis[N]; stack<int> St; set<int> escc[N],bad[N]; struct DSU { VI data; void init(int n) {data.assign(n,-1);} bool unionSet(int x,int y) { x=root(x); y=root(y); if (x!=y) { if (data[y]<data[x]) swap(x,y); data[x]+=data[y]; data[y]=x; } return x!=y; } bool findSet(int x,int y) {return root(x)==root(y);} int root(int x) {return data[x]<0?x:data[x]=root(data[x]);} int size(int x) {return -data[root(x)];} }d; void dfs(int u) { vis[u]=true; for (int v:et[u]) if (!vis[v]) dfs(v); St.push(u); } void findSCC(int u) { vis[u]=true,SCC[u]=nr; for (int v:e[u]) { if (vis[v]) { if (SCC[u]!=SCC[v]) { escc[SCC[u]].insert(SCC[v]); deg[SCC[v]]++; d.unionSet(SCC[u],SCC[v]); } continue; } findSCC(v); } } int main() { read(n); rep(i,0,n) read(a[i]),read(r[i]); d.init(n); rep(i,0,n) { for (int j=i+1;j<n&&a[j]<=a[i]+r[i];j++) e[i].pb(j),et[j].pb(i); for (int j=i-1;j>=0&&a[j]>=a[i]-r[i];j--) e[i].pb(j),et[j].pb(i); } rep(i,0,n) if (!vis[i]) dfs(i); memset(vis,0,sizeof(vis)); while (!St.empty()) { int u=St.top(); St.pop(); if (!vis[u]) { findSCC(u); nr++; } } rep(i,0,nr) { int root=d.root(i); if (SZ(escc[i])==0) dp[i]=2; else { int ilo=1; for (auto it:escc[i]) if (bad[root].find(it)==bad[root].end()) { ilo=(1ll*ilo*dp[it])%mod; bad[root].insert(it); } dp[i]=(dp[i]+1+ilo)%mod; } if (!deg[i]) s[root]=(s[root]+dp[i])%mod; } int ans=1; rep(i,0,n) if (s[i]!=0) ans=(1ll*ans*s[i])%mod; printf("%d\n",ans); }
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> using namespace std; #define rep(i,a,n) for (int i=a;i<n;i++) #define per(i,a,n) for (int i=n-1;i>=a;i--) #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define fi first #define se second #define SZ(x) ((int)(x).size()) typedef vector<int> VI; typedef long long ll; typedef pair<int,int> PII; typedef double db; //mt19937 mrand(random_device{}()); const ll mod=1000000007; //int rnd(int x) { return mrand() % x;} ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} int gcd(int a,int b) { return b?gcd(b,a%b):a;} // head const int N=4e5+5; #define INF 0x3f3f3f3f template<class T> inline void read(T &x) { x=0; int c=getchar(),f=1; for (;!isdigit(c);c=getchar()) if (c==45) f=-1; for (;isdigit(c);c=getchar()) (x*=10)+=f*(c-'0'); } int n,nr,dp[N],s[N],SCC[N],deg[N]; ll a[N],r[N]; VI e[N],et[N]; bool vis[N]; stack<int> St; set<int> escc[N],bad[N]; struct DSU { VI data; void init(int n) {data.assign(n,-1);} bool unionSet(int x,int y) { x=root(x); y=root(y); if (x!=y) { if (data[y]<data[x]) swap(x,y); data[x]+=data[y]; data[y]=x; } return x!=y; } bool findSet(int x,int y) {return root(x)==root(y);} int root(int x) {return data[x]<0?x:data[x]=root(data[x]);} int size(int x) {return -data[root(x)];} }d; void dfs(int u) { vis[u]=true; for (int v:et[u]) if (!vis[v]) dfs(v); St.push(u); } void findSCC(int u) { vis[u]=true,SCC[u]=nr; for (int v:e[u]) { if (vis[v]) { if (SCC[u]!=SCC[v]) { escc[SCC[u]].insert(SCC[v]); deg[SCC[v]]++; d.unionSet(SCC[u],SCC[v]); } continue; } findSCC(v); } } int main() { read(n); rep(i,0,n) read(a[i]),read(r[i]); d.init(n); rep(i,0,n) { for (int j=i+1;j<n&&a[j]<=a[i]+r[i];j++) e[i].pb(j),et[j].pb(i); for (int j=i-1;j>=0&&a[j]>=a[i]-r[i];j--) e[i].pb(j),et[j].pb(i); } rep(i,0,n) if (!vis[i]) dfs(i); memset(vis,0,sizeof(vis)); while (!St.empty()) { int u=St.top(); St.pop(); if (!vis[u]) { findSCC(u); nr++; } } rep(i,0,nr) { int root=d.root(i); if (SZ(escc[i])==0) dp[i]=2; else { int ilo=1; for (auto it:escc[i]) if (bad[root].find(it)==bad[root].end()) { ilo=(1ll*ilo*dp[it])%mod; bad[root].insert(it); } dp[i]=(dp[i]+1+ilo)%mod; } if (!deg[i]) s[root]=(s[root]+dp[i])%mod; } int ans=1; rep(i,0,n) if (s[i]!=0) ans=(1ll*ans*s[i])%mod; printf("%d\n",ans); } |