[AHOI2013]作业

[AHOI2013]作业

题目大意:

给定一个长度为(n(nle10^5))的数列(A(1le A_ile n))(m(mle10^6))次询问,每次询问区间([l,r])内满足(ale A_ile b)的数有多少,去重后又有多少。

思路:

莫队+分块。

时间复杂度(mathcal O(nsqrt n))

源代码:

#include<cmath>
#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
	register char ch;
	while(!isdigit(ch=getchar()));
	register int x=ch^'0';
	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
	return x;
}
const int N=1e5+1,M=1e6;
int n,m,block,a[N],ans0[M],ans1[M],cnt[N],sum[N],tot[N],bel[N],beg[N],end[N];
struct Query {
	int l,r,a,b,id;
	bool operator < (const Query &rhs) const {
		if(l/block==rhs.l/block) return r<rhs.r;
		return l/block<rhs.l/block;
	}
};
Query q[M];
inline void ins(const int &x) {
	if(!cnt[x]++) tot[bel[x]]++;
	sum[bel[x]]++;
}
inline void del(const int &x) {
	if(!--cnt[x]) tot[bel[x]]--;
	sum[bel[x]]--;
}
inline std::pair<int,int> query(const int &l,const int &r) {
	int ret0=0,ret1=0;
	if(bel[l]==bel[r]) {
		for(register int i=l;i<=r;i++) {
			ret0+=cnt[i];
			ret1+=!!cnt[i];
		}
		return std::make_pair(ret0,ret1);
	}
	for(register int i=l;i<=end[bel[l]];i++) {
		ret0+=cnt[i];
		ret1+=!!cnt[i];
	}
	for(register int i=bel[l]+1;i<bel[r];i++) {
		ret0+=sum[i];
		ret1+=tot[i];
	}
	for(register int i=beg[bel[r]];i<=r;i++) {
		ret0+=cnt[i];
		ret1+=!!cnt[i];
	}
	return std::make_pair(ret0,ret1);
}
int main() {
	n=getint(),m=getint(),block=sqrt(n);
	for(register int i=1;i<=n;i++) a[i]=getint();
	for(register int i=0;i<m;i++) {
		q[i].l=getint();
		q[i].r=getint();
		q[i].a=getint();
		q[i].b=getint();
		q[i].id=i;
	}
	std::sort(&q[0],&q[m]);
	for(register int i=1;i<=n;i++) {
		bel[i]=i/block;
		if(!beg[bel[i]]) beg[bel[i]]=i;
		end[bel[i]]=i;
	}
	for(register int i=0,l=1,r=0;i<m;i++) {
		while(r<q[i].r) ins(a[++r]);
		while(r>q[i].r) del(a[r--]);
		while(l>q[i].l) ins(a[--l]);
		while(l<q[i].l) del(a[l++]);
		const std::pair<int,int> p=query(q[i].a,q[i].b);
		ans0[q[i].id]=p.first;
		ans1[q[i].id]=p.second;
	}
	for(register int i=0;i<m;i++) {
		printf("%d %d
",ans0[i],ans1[i]);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/skylee03/p/9646192.html