题目:
题意:
有 n n n个学生,共有 m m m个等级,给出现在需要我们找的区间的所有 m m m个等级的人数范围,求出所有符合范围的方案数
分析:
对于
n
n
n个学生,求其中的区间,我们如果已经确定了右指针,那么左指针也会变成一个区间,我们将左指针的区间用两个指针表示
每次右指针移动时,我们便对左指针的区间进行修改
代码:
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define LL long long
#define LZX LU
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
using namespace std;
LL x[200005],l[200005],r[200005];
LL c1[200005],c2[200005];
int main()
{
freopen("survey.in","r",stdin);
freopen("survey.out","w",stdout);
LL n=read(),m=read();
for(LL i=1;i<=n;i++) x[i]=read();
LL k=m;
for(LL i=1;i<=m;i++) {l[i]=read();r[i]=read();if(!l[i]) k--;}
LL ans=0,ll=1,rr=1;
for(LL i=1;i<=n;i++)
{
c1[x[i]]++;c2[x[i]]++;
if(c2[x[i]]==l[x[i]]) k--;
while(c1[x[i]]>r[x[i]]) c1[x[ll++]]--;
while(!k&&rr<=i)
{
c2[x[rr]]--;
if(c2[x[rr]]==l[x[rr]]-1) k++;
rr++;
}
ans+=max(rr-ll,0ll);
}
cout<<ans;
return 0;
}