rt,莫队50pts,提交记录,而且错的几个点都是在几百行甚至是几万行之后才出错的,也就是说之前的很大一部分答案都是对的。
代码思路是统计一个区间内不同数的个数,如果不同数的个数等于区间长度就没有重复的。
代码:
// P3901 数列找不同
// 莫队
// 这个做法和 P1972 几乎没有任何区别
#include<cstdio>
#include<cmath>
#include<algorithm>
using std::sort;
const int MAXN = 1e5 + 10;
int n, m, a[MAXN], cnt[MAXN], bsize;
bool ans[MAXN];
struct Mo
{
int l, r, book, id;
bool operator < (const Mo &T) const
{
if(book != T.book) return book < T.book;
return (book & 1) ? r < T.r : r > T.r;
}
}q[MAXN];
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
bsize = sqrt(n);
for(int i = 1; i <= n; i++)
{
scanf("%d%d", &q[i].l, &q[i].r);
q[i].id = i;
q[i].book = (q[i].l - 1) / bsize + 1;
}
sort(q + 1, q + m + 1);
int L = 1, R = 0, tot = 0;//tot 表示不同数的个数
for(int i = 1; i <= m; i++)
{
while(L > q[i].l)
{
L--;
if(++cnt[a[L]] == 1) tot++;
}
while(R < q[i].r)
{
R++;
if(++cnt[a[R]] == 1) tot++;
}
while(L < q[i].l)
{
if(--cnt[a[L]] == 0) tot--;
L++;
}
while(R > q[i].r)
{
if(--cnt[a[R]] == 0) tot--;
R--;
}
ans[q[i].id] = (R - L + 1 == tot);
}
for(int i = 1; i <= m; i++) printf("%s\n",ans[i] ? "Yes" : "No");
return 0;
}