洛谷P3901 数列找不同 基础莫队

洛谷P3901 数列找不同

标签

  • 基础莫队

前言

简明题意

  • 需要查询[L,R]区间所有的数是否都不相同

思路

  • 上莫队吧~cnt是肯定要维护的,然后再维护当前区间不同的数有多少个,设为ans。那么每次add的时候,判断一下x是不是=0的,如果x=0,说明新加了原区间不存在的数,ans就应该++。如果x!=0,那么就只用处理cnt了。remove时,如果cnt[x]==1,说明ans会--,cnt[x]!=1,ans不改变。最后,对每组询问,指针移动完后,只需要判断\(ans==(r-l + 1)\),就是这么简单QAQ

注意事项

总结

  • 莫队维护区间的数是否都不相同。只需要维护区间共有多少个不相同的数。

AC代码

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

const int maxn = 1e5 + 10;

struct Query
{
	int l, r, id, k;
	bool operator < (const Query& a)const
	{
		if (k == a.k)
			return r < a.r;
		return k < a.k;
	}
};

Query query[maxn];

int n, q, a[maxn];

int cnt[maxn], ans;//ans记录出现了多少个不同的数
void add(int x)
{
	x = a[x];
	if (cnt[x]++ == 0)
		ans++;
}
void remove(int x)
{
	x = a[x];
	if (cnt[x]-- == 1)
		ans--;
}

int ans0[maxn];
void solve()
{
	scanf("%d%d", &n, &q);
	int len = sqrt(n);
	for (int i = 1; i <= n; i++)
		scanf("%d", &a[i]);
	for (int i = 1; i <= q; i++)
		scanf("%d%d", &query[i].l, &query[i].r), query[i].id = i, query[i].k = (query[i].l - 1) / len + 1;
	sort(query + 1, query + 1 + q);

	int l = 1, r = 0;
	for (int i = 1; i <= q; i++)
	{
		int L = query[i].l, R = query[i].r, id = query[i].id;
		while (l < L) remove(l++);
		while (l > L) add(--l);
		while (r < R) add(++r);
		while (r > R) remove(r--);

		ans0[id] = ans == (r - l + 1);
	}

	for (int i = 1; i <= q; i++)
		printf("%s\n", ans0[i]? "Yes": "No");
}

int main()
{
	solve();
	return 0;
} 
posted @ 2019-08-07 12:48  danzh  阅读(100)  评论(0编辑  收藏  举报