### BZOJ 3809 Gty的二逼妹子序列 莫隊算法+分塊

`#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define M 100100using namespace std;struct query{	int l,r,a,b,_id;	bool operator < (const query &x) const;}queries[1001001];int n,m,block,l=1,r=0;int a[M],belong[M],ans[1001001];int cnt[M],block_cnt[330];bool query :: operator < (const query &x) const{	if( belong[l] != belong[x.l] )		return l < x.l;	return r < x.r;}namespace IStream{	const int L=1<<15;	char buffer[L],*S,*T;	inline char Get_Char()	{		if(S==T)		{			T=(S=buffer)+fread(buffer,1,L,stdin);			if(S==T) return EOF;		}		return *S++;	}	inline int Get_Int()	{		char c;		int re=0;		for(c=Get_Char();c<'0'||c>'9';c=Get_Char());		while(c>='0'&&c<='9')			re=(re<<1)+(re<<3)+(c-'0'),c=Get_Char();		return re;	}}class OStream{	private:		static const int L=1<<15;		char stack[20];int top;		char buffer[L],*S;	public:		OStream()		{			S=buffer;		}		void Put_Int(int x)		{			stack[++top]='\n';			if(!x) stack[++top]='0';			else while(x)				stack[++top]=x%10+'0',x/=10;			while(top)			{				if(S==buffer+L-1)				{					printf("%s",buffer);					S=buffer;				}				*S++=stack[top--];			}		}		~OStream()		{			*S=0;			puts(buffer);		}}os;inline void Update(int x){	cnt[x]++;	if(cnt[x]==1)		block_cnt[belong[x]]++;}inline void Downdate(int x){	cnt[x]--;	if(cnt[x]==0)		block_cnt[belong[x]]--;}int Query(int x,int y){	int i,re=0;	if(belong[y]-belong[x]<=1)	{		for(i=x;i<=y;i++)			re+=(bool)cnt[i];		return re;	}	for(i=belong[x]+1;i<belong[y];i++)		re+=block_cnt[i];	for(i=x;i<=belong[x]*block;i++)		re+=(bool)cnt[i];	for(i=y;i>=(belong[y]-1)*block+1;i--)		re+=(bool)cnt[i];	return re;}int main(){	int i;	cin>>n>>m;	if(n<=10)		block=(int)sqrt(n);	else		block=(int)sqrt(n);	for(i=1;i<=n;i++)	{		a[i]=IStream::Get_Int();		belong[i]=(i-1)/block+1;	}	for(i=1;i<=m;i++)	{		queries[i].l=IStream::Get_Int();		queries[i].r=IStream::Get_Int();		queries[i].a=IStream::Get_Int();		queries[i].b=IStream::Get_Int();		queries[i]._id=i;	}	sort(queries+1,queries+m+1);	for(i=1;i<=m;i++)	{		while(r<queries[i].r)			Update(a[++r]);		while(l>queries[i].l)			Update(a[--l]);		while(r>queries[i].r)			Downdate(a[r--]);		while(l<queries[i].l)			Downdate(a[l++]);		ans[queries[i]._id]=Query(queries[i].a,queries[i].b);	}	for(i=1;i<=m;i++)		os.Put_Int(ans[i]);	return 0;}`