不知道为什么线段树区间更新专题里有这题。。
可以用莫队解,也可以直接开数组解
/* n个询问,m个元素 O(m*m):记录每个元素出现次数,筛掉出现次数小于数值的数 */ #include<iostream> #include<cstring> #include<cstdio> #define maxn 100005 using namespace std; int a[maxn],tot[maxn],s[maxn];//只要统计十万以内的情况 struct Query{ int l,r,ans; }q[maxn];//询问 int main(){ int n,m; while(scanf("%d%d",&m,&n)==2){ memset(q,0,sizeof q); memset(s,0,sizeof s); memset(a,0,sizeof a); memset(tot,0,sizeof tot); for(int i=1;i<=m;i++){ scanf("%d",&a[i]); if(a[i]<=m) tot[a[i]]++; } for(int i=1;i<=n;i++) scanf("%d%d",&q[i].l,&q[i].r); for(int i=1;i<=m;i++)//统计值小于m的数的出现次数即可,i是当前值 if(i<=tot[i]){//i不大于其出现次数才能对答案有贡献 for(int j=1;j<=m;j++) s[j]=s[j-1]+(a[j]==i);//a[j]等于i for(int j=1;j<=n;j++) if(s[q[j].r]-s[q[j].l-1] == i) q[j].ans++;//区间[l,r]之间的i出现次数等于i } for(int i=1;i<=n;i++) printf("%d ",q[i].ans); } return 0; }