洛谷P3901 数列找不同

莫队裸题,我们只需要维护这个区间内出现一次的数的个数,判断ans==(e[i].r-e[i].l+1)就好,因为若没有重复,他们应该是相等的

代码(感觉上我的码风还凑合)

//By AcerMo 
#include
#include
#include
#include
#include
using namespace std;
const int M=100500;
struct Mo{int l,r,id,ans;}e[M];
int n,m,block,c[M];
int bloc[M],cnt,tot[M];
inline bool cmp1(Mo a,Mo b)
{
	if (bloc[a.l]==bloc[b.l]) return a.r'9'||ch<'0') ch=getchar();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x;
} 
inline void slove()
{
	int l=1,r=0,ans=0;
	for (int i=1;i<=m;i++)
	{
		while(le[i].l) if(++tot[c[--l]]==1) ans++;
                while(re[i].r) if(--tot[c[r--]]==0) ans--;
		if (ans==(e[i].r-e[i].l+1)) e[i].ans=1;
		else e[i].ans=0;
	}
	return ;
}
int main()
{
	n=read();m=read();block=sqrt(n);
	for (int i=1;i<=n;i++) c[i]=read();
	for (int i=1;i<=n;i++)
	bloc[i]=(i-1)/block+1;
	for (int i=1;i<=m;i++)
	    e[i].l=read(),e[i].r=read(),e[i].id=i;
	sort(e+1,e+m+1,cmp1);
	slove();
	sort(e+1,e+m+1,cmp2);
	for (int i=1;i<=m;i++) 
	if (e[i].ans) puts("Yes");
	else puts("No");
	return 0;
}


你可能感兴趣的:(莫队)