CF220B Little Elephant and Array

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\n",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;
}
posted @ 2020-12-03 15:20  Seaway-Fu  阅读(105)  评论(0编辑  收藏  举报