牛客小白月赛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.选座椅(双指针)的主要内容,如果未能解决你的问题,请参考以下文章