Non-Puzzle: Segment Pair

Non-Puzzle: Segment Pair
时间限制(普通/Java):2000MS/4000MS 内存限制:262144KByte

描述

输入

输出

样例输入

3
1 4 6 7
2 5 3 5
1 3 5 7

样例输出

2

思路

枚举区间左端点 x,则要满足区间的交包含x,并且不包含 x − 1。

考虑计算包含 x 的方案数,则每对区间的贡献为0,1 或 2(代表有几个区间包含点 x),方案数就是所有贡献的乘积。

然后要扣除包含 x − 1 的方案数。实质上扣除的是同时包含 x 和 x − 1两个点的方案数,同样是若干个 0, 1, 2 的乘积。

对 x 作扫描线,实时维护 0, 1, 2 的个数。

AC代码

#include <bits/stdc++.h>
using namespace std;
int mod=1e9+7;
vector<int>v1[500005],v2[500005];
int t[500005],p2[500005];
void solve()
{
    int n,ans=0,sum=0,now=0;
    cin>>n;
    p2[0]=1;
    for(int i=1;i<=n;i++)
        p2[i]=p2[i-1]*2%mod;
    int a,b;
    for(int i=1;i<=n;i++)
    {
        cin>>a>>b;
        v1[a].push_back(i);
        v2[b].push_back(i);
        cin>>a>>b;
        v1[a].push_back(i);
        v2[b].push_back(i);
    }
    for(int i=1;i<500005;i++)
    {
        for(int j : v1[i])
        {
            t[j]++;
            if(t[j]==1) sum++;
            if(sum==n) (ans+=p2[now])%=mod;
            if(t[j]==2) now++;
        }
        for(int j : v2[i])
        {
            t[j]--;
            if(t[j]==0) sum--;
            if(t[j]==1) now--;
        }
    }
    cout<<ans<<endl;
}
signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int _=1;
//    cin>>_;
    while(_--)
    {
        solve();
    }
}
posted @ 2023-08-14 23:18  Minza  阅读(20)  评论(0编辑  收藏  举报