P3901 数列找不同

题目描述

现有数列 \(A_1,A_2,\ldots,A_N\)\(Q\) 个询问 \((L_i,R_i)\),询问 \(A_{L_i} ,A_{L_i+1},\ldots,A_{R_i}\) 是否互不相同。

输入格式

第一行,两个整数\(N,Q\)
第二行,\(N\) 个整数\(A_1, A_2, \ldots , A_N\)
接下来 \(Q\) 行,每行两个整数 \(L_i,R_i\)

输出格式

对每个询问输出一行,YesNo

样例 #1

样例输入 #1

4 2
1 2 3 2
1 3
2 4

样例输出 #1

Yes
No

提示

对于 \(50\%\) 的数据,\(N,Q \le 10^3\)
对于 \(100\%\) 的数据,\(1 \le N,Q \le 10^5\)\(1 \le A_i \le N\)\(1 \le L_i \le R_i \le N\)

分析

考虑维护一个区间桶,发现可以区间左右端点进行转移,那么考虑普通莫队即可。

#include<bits/stdc++.h>
using namespace std;
int n,m,bl,pos[100005],a[100005],ans[100005],cnt[100005],now;
struct node{int l,r,id;}q[100005];
bool cmp(node x,node y){return pos[x.l]^pos[y.l]?pos[x.l]<pos[y.l]:x.r<y.r;}
void add(int x){if(cnt[a[x]]==0)++now;++cnt[a[x]];}
void del(int x){--cnt[a[x]];if(cnt[a[x]]==0)--now;}
int main(){
	cin>>n>>m,bl=sqrt(n);
	for(int i=1;i<=n;i++)cin>>a[i],pos[i]=(i-1)/bl+1;
	for(int i=1;i<=m;i++)cin>>q[i].l>>q[i].r,q[i].id=i;
	sort(q+1,q+m+1,cmp);
	for(int i=1,l=1,r=0;i<=m;i++){
		while(q[i].l<l)add(--l);
		while(q[i].r>r)add(++r);
		while(q[i].l>l)del(l++);
		while(q[i].r<r)del(r--);
		ans[q[i].id]=(now==r-l+1);
	}
	for(int i=1;i<=m;i++)puts(ans[i]?"Yes":"No");
	return 0;
}
posted @ 2023-06-24 14:12  alex_liu09  阅读(10)  评论(0)    收藏  举报