[CF1028D] Order book

Description

给定两个集合 (A,B),要求在任意时刻 (A) 中元素小于 (B) 中元素。每次操作可以添加一个元素 (x) 到任意一个集合(由程序来选择)或者删除一个元素 (x),保证添加的元素互不相同,删除的元素一定存在,并要求删除的元素必须是 (A) 的最大值或者 (B) 的最小值。求方案数。

Solution

每次删除操作会对前面所有的添加操作产生某种限制。

假设本次删除 (x),那么前面所有小于 (x) 的元素都必须被加入 (A),大于 (x) 的元素都必须被加入 (B),等于 (x) 的元素,如果 (x) 小于 (A) 的最大值则必须被加入 (A),大于 (B) 的最小值则必须被加入 (B),否则可以任意选择,总方案数 ( imes 2)

但最后一次删除后还可能有若干添加操作,对于这些添加操作,我们在删除其中小于 (A) 的最大值、大于 (B) 的最小值者后,剩余的元素可以任取分割界,左侧加入 (A) 右侧加入 (B)。假设元素一共有 (c) 个,则答案 ( imes (c+1))

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 1000005;
const int mod = 1e9+7;

int n,p,ans=1;
string str;
set <int> s;

signed main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    int l=-1e9,r=1e9,cnt=0,ans=1;
    s.insert(l);
    s.insert(r);
    while(n--)
    {
        cin>>str>>p;
        if(str=="ADD")
        {
            s.insert(p);
            if(l<=p && p<=r) ++cnt;
        }
        else
        {
            cnt=0;
            if(p<l || p>r) ans=0;
            if(!(p==l || p==r)) ans*=2, ans%=mod;
            auto i=s.lower_bound(p);
            ++i;
            r=*i;
            --i;
            --i;
            l=*i;
            ++i;
            s.erase(i);
        }
    }
    ans*=cnt+1;
    ans%=mod;
    cout<<ans<<endl;
}
原文地址:https://www.cnblogs.com/mollnn/p/13565028.html