成绩调研

23 篇文章 0 订阅
14 篇文章 0 订阅

题目大意

求有多少个区间满足权值为i的数量在[li,ri]内。

扫一扫

我们枚举区间右端点,左端点的可取范围是一段区间。
尝试用两个堆维护左端点的最大值和最小值。
对于第i种权值,我们可以通过指针跳跳跳获得在位置i时左端点的左界和右界,所以一个堆保存所有权值的左界另一个保存右界。
注意l=0以及r=0的情况。

#include<cstdio>
#include<algorithm>
#include<set>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
typedef long long LL;
const int maxn=200000+10;
multiset<int> s1,s2;
int L[maxn],R[maxn],ll[maxn],rr[maxn],fi[maxn],right[maxn],id[maxn],cnt[maxn],a[maxn];
int i,j,k,l,r,t,n,m;
LL ans;
int read(){
    int x=0;
    char ch=getchar();
    while (ch<'0'||ch>'9') ch=getchar();
    while (ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x;
}
int main(){
    freopen("survey.in","r",stdin);freopen("survey.out","w",stdout);
    n=read();m=read();
    fo(i,1,n) a[i]=read();
    fo(i,1,m) L[i]=read(),R[i]=read();
    fo(i,1,m) cnt[i]=1;
    fd(i,n,1){
        right[i]=fi[a[i]];
        fi[a[i]]=i;
    }
    fo(i,1,n) id[i]=++cnt[a[i]];
    id[0]=1;
    fo(i,1,m){
        ll[i]=1;
        s1.insert(-ll[i]);
        if (L[i]){
            rr[i]=0;
            s2.insert(rr[i]);
        }
    }
    fo(i,1,n){
        t=a[i];
        if (L[t]){
            while (id[i]-id[rr[t]]+1>L[t]){
                s2.erase(s2.find(rr[t]));
                if (!rr[t]) rr[t]=fi[t];else rr[t]=right[rr[t]];
                s2.insert(rr[t]);
            }
        }
        while (id[i]-id[ll[t]-1]+1>R[t]+1){
            s1.erase(s1.find(-ll[t]));
            if (ll[t]==1) ll[t]=fi[t]+1;else ll[t]=right[ll[t]-1]+1;
            s1.insert(-ll[t]);
        }
        l=-(*s1.begin());
        if (!s2.empty()) r=*s2.begin();else r=i;
        if (l<=r) ans+=(LL)(r-l+1);
    }
    printf("%lld\n",ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值