Codeforces Round #804 (Div. 2) C(mex)

题目描述:

给定一个长度为n的数组a,其中每个a[i]的范围在0~n-1 且每个数仅出现一次 ,其中b数组满足对a和b数组任意的任意区间1<=l<=r<=n,其中mex{a[l],a[l+1]...a[r]}==mex{b[l],b[l+1]...b[r]},mex是求该区间内未出现的最小非负整数,如mex{1,2,3}=0,mex{0,1,2,3}=4,输出满足的b数组的个数

题解:

我们可以用p来存每个数字在a数组里的位置,初始l=r=p[0],

然后遍历i从0~n-1,每次查看p[i]的位置是否在区间l到r内,

如果不在l到r内,更行区间,且说明这个位置的数放上去后是区间的边界,mex值在区间改变后也会发生改变,改位置就是固定的,ans不做处理

如果在l到r内,因为i之前的数组的位置都已经找过了,而l和r的位置也存的是i之前的数,那么在这个区间内,除了已经找过的数,其他任意位置是可以随意放的,这时候的任意位置个数就是r-l+1-i,(注意这里的i意思是已经确定了i个数,如果减去,就意味着还有这么些个位置没有放),所以ans*=(这些位置个数)

#include <bits/stdc++.h>
#define rep(i,n,m) for(int i=n;i<=m;++i)
#define per(i,n,m) for(int i=n;i>=m;--i)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N=100050;
const ll MOD=1e9+7;
ll a[N];
map<ll,ll>p;
void solve()
{
    int n;cin>>n;
    p.clear();
    rep(i,1,n){
        cin>>a[i];
        p[a[i]]=i;   //记录每个数在数组a的位置
    }
    ll l=p[0],r=p[0],ans=1;   //初始化区间和答案
    rep(i,1,n-1){
        if(p[i]>l&&p[i]<r){
             ans*=1LL*(r-l+1-i);  //ans*(区间内未出现过数的位置)
             ans%=MOD;
        }
        l=min(l,p[i]);
        r=max(r,p[i]);
    }
    cout<<ans<<endl;
}
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    int n;cin>>n;
    while(n--)solve();
    return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

女人只会影响我敲代码的速度QAQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值