#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN=30000; const ll MOD=1e9+7; pair<int, int> arr[MAXN+5]; vector<int> adj[MAXN+5]; //reverse int cnt[MAXN+5]; //do ilu mozna dojsc bitset<30005> bs[MAXN+5]; ll fpow(ll a, ll p) { ll res=1; while(p){ if(p & 1){ res = (res * a) % MOD; } p/=2; a = (a * a) % MOD; } return res; } ll fact(ll n) { ll res=1; for(ll i=2;i<=n;i++){ res = (res * i) % MOD; } return res; } //drzewo maximum, update na przedziale, pytanie o punkt int seg[8*MAXN+5]; void update(int v, int tl, int tr, int l, int r, int val) { if(l <= tl && r >= tr){ seg[v]=val; return; } int tm = (tl+tr)/2; if(l <= tm) update(v*2, tl, tm, l, r, val); if(r > tm) update(v*2+1, tm+1, tr, l, r, val); } int query(int v, int tl, int tr, int pos) { if(tl == tr){ return seg[v]; } int tm = (tl+tr)/2; if(pos <= tm) return max(query(v*2, tl, tm, pos), seg[v]); else return max(query(v*2+1, tm+1, tr, pos), seg[v]); } void solve() { int n; cin >> n; for(int i=1;i<=n;i++){ int l,r; cin >> l >> r; arr[i].first=l; arr[i].second=r; } for(int i=1;i<=n;i++){ int l = arr[i].first; int r = arr[i].second; int qry1 = query(1, 1, 2*n, l); int qry2 = query(1, 1, 2*n, r); if(qry1) adj[qry1].push_back(i); if(qry2 && qry2!=qry1) adj[qry2].push_back(i); update(1, 1, 2*n, l, r, i); } for(int i=n;i>=1;i--){ bs[i][i]=1; for(int j : adj[i]){ bs[i] |= bs[j]; } cnt[i]=bs[i].count() - 1; } ll nf = fact(n); ll ans=0; for(int i=1;i<=n;i++){ ans += nf * fpow(cnt[i]+1, MOD-2); //ans += nf / (cnt[i]+1); //ans += fpow(cnt[i]+1, MOD-2); ans %= MOD; } //cout << ans; cout << (ans * fpow(nf, MOD-2)) % MOD; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); 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 97 98 99 100 101 102 103 104 105 106 | #include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN=30000; const ll MOD=1e9+7; pair<int, int> arr[MAXN+5]; vector<int> adj[MAXN+5]; //reverse int cnt[MAXN+5]; //do ilu mozna dojsc bitset<30005> bs[MAXN+5]; ll fpow(ll a, ll p) { ll res=1; while(p){ if(p & 1){ res = (res * a) % MOD; } p/=2; a = (a * a) % MOD; } return res; } ll fact(ll n) { ll res=1; for(ll i=2;i<=n;i++){ res = (res * i) % MOD; } return res; } //drzewo maximum, update na przedziale, pytanie o punkt int seg[8*MAXN+5]; void update(int v, int tl, int tr, int l, int r, int val) { if(l <= tl && r >= tr){ seg[v]=val; return; } int tm = (tl+tr)/2; if(l <= tm) update(v*2, tl, tm, l, r, val); if(r > tm) update(v*2+1, tm+1, tr, l, r, val); } int query(int v, int tl, int tr, int pos) { if(tl == tr){ return seg[v]; } int tm = (tl+tr)/2; if(pos <= tm) return max(query(v*2, tl, tm, pos), seg[v]); else return max(query(v*2+1, tm+1, tr, pos), seg[v]); } void solve() { int n; cin >> n; for(int i=1;i<=n;i++){ int l,r; cin >> l >> r; arr[i].first=l; arr[i].second=r; } for(int i=1;i<=n;i++){ int l = arr[i].first; int r = arr[i].second; int qry1 = query(1, 1, 2*n, l); int qry2 = query(1, 1, 2*n, r); if(qry1) adj[qry1].push_back(i); if(qry2 && qry2!=qry1) adj[qry2].push_back(i); update(1, 1, 2*n, l, r, i); } for(int i=n;i>=1;i--){ bs[i][i]=1; for(int j : adj[i]){ bs[i] |= bs[j]; } cnt[i]=bs[i].count() - 1; } ll nf = fact(n); ll ans=0; for(int i=1;i<=n;i++){ ans += nf * fpow(cnt[i]+1, MOD-2); //ans += nf / (cnt[i]+1); //ans += fpow(cnt[i]+1, MOD-2); ans %= MOD; } //cout << ans; cout << (ans * fpow(nf, MOD-2)) % MOD; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); solve(); return 0; } |