#include <bits/stdc++.h> #define FOR(i,p,k) for(int i=(p);i<=(k);++i) #define REP(i,n) FOR(i,0,(n)-1) #define ssize(x) (int((x).size())) #define all(x) (x).begin(),(x).end() #define rall(x) (x).rbegin(),(x).rend() #define gc getchar_unlocked #define fi first #define se second using namespace std; typedef pair<int, int> pii; typedef long long ll; constexpr ll mod = 1000000007ll; void wczytaj(int &a){ int c = gc(); while(c < '0' || c > '9') c = gc(); for(a = 0; c >= '0' && c <= '9'; c = gc()) a = 10*a+c-'0'; } ll pot(ll a, ll b = mod-2ll){ ll ret = 1ll; for(; b; b>>=1, a=(a*a)%mod) if(b&1ll) ret = (ret*a)%mod; return ret; } void solve(){ int n; wczytaj(n); vector<pii> wejscie(n+1); wejscie[0] = {0, 2*n+1}; int loog = 1; while((1<<loog) <= n) ++loog; vector tab_lewo(loog+1, vector(n+1, 0)); vector tab_prawo(loog+1, vector(n+1, 0)); set<pii> secik = {{1,0}, {2*n+1,0}, {2*n+2,0}}; auto podziel = [&](int poz){ auto it = secik.lower_bound({poz, 0}); if(it->fi != poz) secik.emplace(poz, prev(it)->se); }; auto kolor = [&](int poz){ return prev(secik.lower_bound({poz+1, 0}))->se; }; FOR(i, 1, n){ int a, b; wczytaj(a), wczytaj(b); wejscie[i] = {a, b}; tab_lewo[0][i] = kolor(a); tab_prawo[0][i] = kolor(b); podziel(a), podziel(b+1); auto it = secik.lower_bound({a, 0}); while(it->fi <= b) it = secik.erase(it); secik.emplace(a, i); } FOR(j, 1, loog) FOR(i, 1, n){ tab_lewo[j][i] = tab_lewo[j-1][tab_lewo[j-1][i]]; tab_prawo[j][i] = tab_prawo[j-1][tab_prawo[j-1][i]]; } vector<int> osiagalne(n+1, 1); for(int i = n+1; --i;){ int a = tab_lewo[0][i]; int b = tab_prawo[0][i]; osiagalne[a] += osiagalne[i]; osiagalne[b] += osiagalne[i]; if(wejscie[a].se > wejscie[b].fi){ osiagalne[min(a, b)] -= osiagalne[i]; continue; } auto czy_git = [&](int lewo){ if(b < lewo) return wejscie[lewo].se < wejscie[i].se; int prawo = b; for(int j = loog+1; ~--j;) if(int t = tab_lewo[j][prawo]; t >= lewo) prawo = t; return wejscie[lewo].se < wejscie[prawo].fi; }; int lewo = a; if(!czy_git(lewo)){ osiagalne[lewo] -= osiagalne[i]; continue; } for(int j = loog+1; ~--j;) if(int t = tab_prawo[j][lewo]; czy_git(t)) lewo = t; osiagalne[tab_prawo[0][lewo]] -= osiagalne[i]; } ll wyn = 0ll; FOR(i, 1, n) wyn = (wyn+pot(osiagalne[i]))%mod; printf("%lld", wyn); } int main(){ solve(); 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 | #include <bits/stdc++.h> #define FOR(i,p,k) for(int i=(p);i<=(k);++i) #define REP(i,n) FOR(i,0,(n)-1) #define ssize(x) (int((x).size())) #define all(x) (x).begin(),(x).end() #define rall(x) (x).rbegin(),(x).rend() #define gc getchar_unlocked #define fi first #define se second using namespace std; typedef pair<int, int> pii; typedef long long ll; constexpr ll mod = 1000000007ll; void wczytaj(int &a){ int c = gc(); while(c < '0' || c > '9') c = gc(); for(a = 0; c >= '0' && c <= '9'; c = gc()) a = 10*a+c-'0'; } ll pot(ll a, ll b = mod-2ll){ ll ret = 1ll; for(; b; b>>=1, a=(a*a)%mod) if(b&1ll) ret = (ret*a)%mod; return ret; } void solve(){ int n; wczytaj(n); vector<pii> wejscie(n+1); wejscie[0] = {0, 2*n+1}; int loog = 1; while((1<<loog) <= n) ++loog; vector tab_lewo(loog+1, vector(n+1, 0)); vector tab_prawo(loog+1, vector(n+1, 0)); set<pii> secik = {{1,0}, {2*n+1,0}, {2*n+2,0}}; auto podziel = [&](int poz){ auto it = secik.lower_bound({poz, 0}); if(it->fi != poz) secik.emplace(poz, prev(it)->se); }; auto kolor = [&](int poz){ return prev(secik.lower_bound({poz+1, 0}))->se; }; FOR(i, 1, n){ int a, b; wczytaj(a), wczytaj(b); wejscie[i] = {a, b}; tab_lewo[0][i] = kolor(a); tab_prawo[0][i] = kolor(b); podziel(a), podziel(b+1); auto it = secik.lower_bound({a, 0}); while(it->fi <= b) it = secik.erase(it); secik.emplace(a, i); } FOR(j, 1, loog) FOR(i, 1, n){ tab_lewo[j][i] = tab_lewo[j-1][tab_lewo[j-1][i]]; tab_prawo[j][i] = tab_prawo[j-1][tab_prawo[j-1][i]]; } vector<int> osiagalne(n+1, 1); for(int i = n+1; --i;){ int a = tab_lewo[0][i]; int b = tab_prawo[0][i]; osiagalne[a] += osiagalne[i]; osiagalne[b] += osiagalne[i]; if(wejscie[a].se > wejscie[b].fi){ osiagalne[min(a, b)] -= osiagalne[i]; continue; } auto czy_git = [&](int lewo){ if(b < lewo) return wejscie[lewo].se < wejscie[i].se; int prawo = b; for(int j = loog+1; ~--j;) if(int t = tab_lewo[j][prawo]; t >= lewo) prawo = t; return wejscie[lewo].se < wejscie[prawo].fi; }; int lewo = a; if(!czy_git(lewo)){ osiagalne[lewo] -= osiagalne[i]; continue; } for(int j = loog+1; ~--j;) if(int t = tab_prawo[j][lewo]; czy_git(t)) lewo = t; osiagalne[tab_prawo[0][lewo]] -= osiagalne[i]; } ll wyn = 0ll; FOR(i, 1, n) wyn = (wyn+pot(osiagalne[i]))%mod; printf("%lld", wyn); } int main(){ solve(); return 0; } |