CF220B Little Elephant and Array
题目描述
小象喜欢和数组玩。现在有一个数组a,含有n个正整数,记第i个数为ai
现在有m个询问,每个询问包含两个正整数lj和rj(1<=lj<=rj<=n),小象想知道在Alj到Arj之中有多少个数x,其出现次数也为x
输入格式
第一行n和m,n表示数组大小,m表示询问个数,下一行为数组的值,再下m行,每行两个数lj和rj,描述如题面
输出格式
共m行,每行一个数,表示答案
题解:
莫队。
代码:
#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
#include<cstdio>
#include<algorithm>
#include<cmath>
#define R register
using namespace std;
inline int read()
{
int X=0; bool flag=1; char ch=getchar();
while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
if(flag) return X;
return ~(X-1);
}
const int maxn=1e6+6;
int n,q,pj,tmp;
int a[maxn],b[maxn];
int cnt[maxn];
int ans[maxn];
struct node
{
int l,r;
int id;
}que[maxn];
inline void solve1()
{
R int i;
for(i=1;i<=q;++i)
{
int l,r;
l=read();r=read();
if(r-l+1==a[l])
puts("1");
else
puts("0");
}
}
inline bool cmp(node x,node y)
{
if(b[x.l]==b[y.l])
return b[x.l]&1?x.r<y.r:x.r>y.r;
return b[x.l]<b[y.l];
}
inline void add(int x)
{
if(cnt[a[x]]==a[x])
tmp--;
cnt[a[x]]++;
if(cnt[a[x]]==a[x])
tmp++;
}
inline void del(int x)
{
if(cnt[a[x]]==a[x])
tmp--;
cnt[a[x]]--;
if(cnt[a[x]]==a[x])
tmp++;
}
inline void solve2()
{
R int i;
for(i=1;i<=q;++i)
{
que[i].l=read();que[i].r=read();
que[i].id=i;
}
int bl=pow(n,1.11/2);
for(i=1;i<=n;++i)
b[i]=(i-1)/bl+1;
sort(que+1,que+q+1,cmp);
int l=1,r=0;
for(i=1;i<=q;++i)
{
while(l<que[i].l)
del(l++);
while(r>que[i].r)
del(r--);
while(l>que[i].l)
add(--l);
while(r<que[i].r)
add(++r);
ans[que[i].id]=tmp;
}
for(i=1;i<=q;++i)
printf("%d
",ans[i]);
}
signed main()
{
n=read();q=read();
R int i;
for(i=1;i<=n;++i)
{
a[i]=read();
if(a[i]==a[1])
pj++;
}
if(pj==n)
solve1();
else
solve2();
return 0;
}