求区间(l-r)内恰好出现k次数的个数
#include <iostream>
#include <algorithm>
#include <string.h>
#include <math.h>
using namespace std;
const int maxn=1e5+10;
struct Mo{
int l;
int r;
int id;
int oid;
};Mo mo[maxn];
int sto[maxn];
int cnt[maxn],ans,k,m,n;
int a[maxn];
bool cmp(Mo a,Mo b)
{
if (a.id==b.id)
return a.r<b.r;
else
return a.l<b.l;
}
void add(int l)
{
int v=cnt[a[l]];
cnt[a[l]]++;
if (v<k&&cnt[a[l]]>=k)
ans++;
}
void remove(int l)
{
int v=cnt[a[l]];
cnt[a[l]]--;
if (v>=k&&cnt[a[l]]<k)
ans--;
}
void init(int n)
{
int l,r;
int li=sqrt(n);
for (int i=0;i<m;i++)
{
cin>>l>>r;
mo[i].l=l;
mo[i].r=r;
mo[i].id=(l-1)/li;
mo[i].oid=i;
}
sort(mo,mo+m,cmp);
}
int main()
{
int l,r,v;
while (cin>>n>>m>>k)
{
memset(cnt,0,sizeof(cnt));
v=0;
for (int i=1;i<=n;i++)
cin>>a[i];
init(n);
int l=r=1;
add(1);
ans=0;
for (int i=0;i<m;i++)
{
while (l<mo[i].l) {remove(l);l++;}
while (l>mo[i].l) {l--;add(l);}
while (r<mo[i].r) {r++;add(r);}
while (r>mo[i].r) {remove(r);r--;}
sto[mo[i].oid]=ans;
}
for (int i=0;i<m;i++)
cout<<sto[i]<<endl;
}
return 0;
}