题目链接
题意,给定n个数(n<=1e5)每个数<=1e9;然后给定m个区间计算每个区间内 x出现x次的数字有几个即3出现了三次算一个,2出现了2次也算一个。
因为数据太大不能开1e9的数组但是他要计算次数大于1e5的数肯定不行因为数据最多一共有1e5个所以大于1e5的数据我们就忽略他不统计他的个数。
而且代码中是把所有区间全部进行统计之后然后总的输出答案。
#include <iostream>
#define mn 1000010
using namespace std;
int n,m,l[mn],r[mn],ans[mn],a[mn],s[mn],b[mn];
int main()
{
cin>>n>>m;
for(int i=1; i<=n; i++)
cin>>a[i],b[a[i]<=n?a[i]:0]++; //首先对数据计数如果符合范围就把他出现的次数+1
for(int i=1; i<=m; i++)
cin>>l[i]>>r[i];//输入m个区间
for(int i=1; i<=n; i++)//每次循环就判断i的出现次数也就是说每次都只判断当前这个数i在每个区间内出现的次数
if(i<=b[i])//如果i>b[i]就说明i根本不可能符合任意一个区间;
{
for(int j=1; j<=n; j++)
{
s[j]=s[j-1]+(a[j]==i);//前缀和当前位置的数字是不是i
//cout<<s[j]<<' ';
}
//cout<<endl;
for(int j=1; j<=m; j++)
if(s[r[j]]-s[l[j]-1]==i)
ans[j]++;
}
for(int i=1; i<=m; i++)
cout<<ans[i]<<endl;
}
为什么减得是 s[l[j]-1]而不是s[l[j]]假设一个序列是 2 2 2 那么对应位置出现的2的次数是1 2 3 那么在【2,3】区间内2出现了2次是s[3]-s[1].