牛客小白月赛61 F.选座椅(双指针)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客小白月赛61 F.选座椅(双指针)相关的知识,希望对你有一定的参考价值。

牛客小白月赛61 F.选座椅(双指针)

显然 ( l , r ) (l,r) (l,r)满足 ( l , r + 1 ) (l,r+1) (l,r+1)满足。

那么可以考虑双指针,枚举 l l l,然后计算贡献是一段区间,使用BIT实现区间加。维护满足的种类个数即可。

最后乘上 l e n ! len! len!就是答案。

时间复杂度: O ( n + m ) O(n+m) O(n+m)

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

const int M = (int)1e5;
const int mod = (int)1e9 + 7;

int n, m;
vector<int> v[M + 5];
int cnt[M + 5], tot;
int d[M + 5];

void work()

    scanf("%d %d", &n, &m);
    for(int _ = 0; _ < 3; ++_)
        for(int i = 1, a; i <= m; ++i) 
            scanf("%d", &a);
            v[a].push_back(i);
        
    auto add = [&](int p) 
        for(const int& x: v[p])
            if(++cnt[x] == 1)
                ++tot;
    ;
    
    auto del = [&](int p) 
        for(const int &x: v[p])
            if(--cnt[x] == 0)
                --tot;
    ;
    
    for(int l = 1, r = 0; l <= n; ++l) 
        while(r + 1 <= n && tot < m) add(++r);
        if(tot == m) ++d[r - l + 1], --d[n - l + 2];
        del(l);
    
    
    for(int i = 1, fac = 1; i <= n; ++i) 
        fac = (long long)fac * i % mod;
        d[i] += d[i - 1];
        printf("%lld%c", (long long)fac * d[i] % mod, " \\n"[i == n]);
    


int main()

    work();
    return 0;

以上是关于牛客小白月赛61 F.选座椅(双指针)的主要内容,如果未能解决你的问题,请参考以下文章

牛客白月赛16题解

牛客白月赛13题解

牛客白月赛15题解

F.孤独(牛客小白月赛39)

牛客小白月赛59 F.困难卷积(暴力)

牛客白月赛14题解