给n对区间,要求每对区间恰好选一个使得选出来的n个区间有交集,问有多少方案数
可以从每一个点开始考虑 如果前面的点没有任何可行的方案,那么新点就可以作为左端点,对答案的贡献为 向后扫描的过程中,如果新的点有增加,答案的贡献若为 则可以对答案做统计即为: - 。
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
const int INF = 1e18;
typedef pair<int, int> PII;
const int MOD = 1e9+7;
const int N = 5e5 + 100;
vector<int>in[N],out[N];
int num[N],k;
int qpow(int a,int n) {
if (n == -1) return 0;
int ans = 1;
while (n) {
if (n & 1) ans = ans * a % MOD;
n >>= 1;
a = a * a % MOD;
}
return ans;
}
inline void solve() {
int n;
cin >> n;
for (int i = 1, l, r; i <= n; i++) {
cin >> l >> r;
in[l].push_back(i);
out[r + 1].push_back(i);
cin >> l >> r;
in[l].push_back(i);
out[r + 1].push_back(i);
}
int tot = 0, mx = 5e5, lst = -1;
int ans = 0;
for (int i = 1; i <= mx; i++) {
for (auto v: out[i]) {
if (num[v] == 2) --k;
--num[v];
if (!num[v]) --tot;
}
if (tot < n) lst = -1;
else lst = k;
for (int v: in[i]) {
if (!num[v])++tot;
++num[v];
if (num[v] == 2) ++k;
if (tot == n) {
if (lst == -1 || k > lst) {
ans += qpow(2, k) - qpow(2, lst);
ans += MOD;
ans %= MOD;
}
lst = k;
}
}
}
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
//cin >> t;
while (t--)
solve();
return 0;
}