洛谷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;
}
作者:danzh
QQ:1244536605
CSDN(和博客园同步):https://blog.csdn.net/weixin_42431507
-----------------------------------------------------------------------------------------------
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其
它人怎么样,我们也能够保持自己的本色走下去。
—clj