https://codeforces.com/problemset/problem/220/B
展开
题目描述
The Little Elephant loves playing with arrays. He has array aa , consisting of nn positive integers, indexed from 1 to nn . Let's denote the number with index ii as a_{i}ai .
Additionally the Little Elephant has mm queries to the array, each query is characterised by a pair of integers l_{j}lj and r_{j}rj (1<=l_{j}<=r_{j}<=n)(1<=lj<=rj<=n) . For each query l_{j},r_{j}lj,rj the Little Elephant has to count, how many numbers xx exist, such that number xx occurs exactly xx times among numbers a_{lj},a_{lj}+1,...,a_{rj}alj,alj+1,...,arj .
Help the Little Elephant to count the answers to all queries.
输入格式
The first line contains two space-separated integers nn and mm (1<=n,m<=10^{5})(1<=n,m<=105) — the size of array aa and the number of queries to it. The next line contains nn space-separated positive integers a_{1}a1 , a_{2}a2 , ...... , a_{n}an (1<=a_{i}<=10^{9})(1<=ai<=109) . Next mm lines contain descriptions of queries, one per line. The jj -th of these lines contains the description of the jj -th query as two space-separated integers l_{j}lj and r_{j}rj (1<=l_{j}<=r_{j}<=n)(1<=lj<=rj<=n) .
输出格式
In mm lines print mm integers — the answers to the queries. The jj -th line should contain the answer to the jj -th query.
题意翻译
题目描述
小象喜欢和数组玩。现在有一个数组a,含有n个正整数,记第i个数为ai
现在有m个询问,每个询问包含两个正整数lj和rj(1<=lj<=rj<=n),小象想知道在Alj到Arj之中有多少个数x,其出现次数也为x
输入格式
第一行n和m,n表示数组大小,m表示询问个数,下一行为数组的值,再下m行,每行两个数lj和rj,描述如题面
输出格式
共m行,每行一个数,表示答案
输入输出样例
输入 #1复制
7 2 3 1 2 2 3 3 7 1 7 3 4
输出 #1复制
3 1
看起来是个莫队..但是我莫队还不会呢!
一个数 x 可能对一个询问产生贡献条件是其出现过至少 x 次,这样的数不超过 sqrt(n)个。
然后二维数组前缀和记录到某个位置这个数出现了多少次.(上场的eduD也是这么写压)
然后询问的时候暴力查找满足条件的每一个数能否累加就好了。O((n+q)sqrt(n));
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5+100;
typedef int LL;
LL c[maxn],f[maxn][500],a[maxn],val[maxn];
int main(void)
{
cin.tie(0);std::ios::sync_with_stdio(false);
LL n,m;cin>>n>>m;
for(LL i=1;i<=n;i++){
cin>>a[i];
if(a[i]<=n) c[a[i]]++;
}
LL cnt=0;
for(LL j=1;j<=n;j++) //枚举1-n的数
{
if(c[j]>=j)//均摊是sqrt(n)的
{
val[++cnt]=j;
for(LL i=1;i<=n;i++)//1-n每个位置
{
f[i][j]=f[i-1][j]+(a[i]==j);
}
}
}
while(m--)
{
LL l,r;cin>>l>>r;
LL ans=0;
for(LL i=1;i<=cnt;i++)
{
if(f[r][val[i]]-f[l-1][val[i]]==val[i]) ans++;
}
cout<<ans<<endl;
}
return 0;
}