CF 1699C The Third Problem

標籤: cf

有一个 0..n10..n-1 的排列 aia_i。求有多少个排列 bib_i st 每一个 [l,r][l, r],有 MEXi[l,r]{ai}=MEXi[l,r]{bi}\mathrm{MEX}_{i \in [l, r]} \left\{a_i\right\} = \mathrm{MEX}_{i \in [l, r]}\left\{b_i\right\}

posipos_i 表示 ii 在排列 aa 中的位置。考虑枚举 MEXj[l,r]{aj}\mathrm{MEX}_{j \in [l, r]} \left\{a_j\right\} 的值。如果 MEXj[l,r]{aj}=i\mathrm{MEX}_{j \in [l, r]}\left\{a_j\right\} = ial..ra_{l..r} 一定包含了 0..i10..i-1 的所有值,因此这个 llrr 应当满足 lminj[0,i){posj}l \le \min_{j \in [0, i)} \left\{pos_j\right\}rMEXj[0,i){posj}r \ge \mathrm{MEX}_{j \in [0, i)} \left\{pos_j\right\}。同时,为了保证 bbMEX\mathrm{MEX}aa 相同,对于值 ii,如果 lposirl \le pos_i \le r,则在 bb 中,ii 可以放在 [l,r][l, r] 的任意一个位置,否则必须放在与 aa 相同的位置。

void solve()
{
    int n;
    scanf("%d", &n);
    std::vector<int> a(n);
    for (auto &i : a) scanf("%d", &i);
    std::vector<int> pos(n);
    for (int i = 0; i < n; i++)
        pos[a[i]] = i;
    int l = pos[0], r = pos[0];
    long long ans = 1;
    for (int i = 1; i < n; i++)
    {
        if (l <= pos[i] && pos[i] <= r) ans = ans * (r - l + 1 - i) % MODN; // 注意减去已经安排好位置的 i 个元素.
        l = std::min(l, pos[i]);
        r = std::max(r, pos[i]);
    }
    printf("%lld\n", ans);
}