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