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\)。
输出格式
对每个询问输出一行,Yes 或 No。
样例 #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;
}

浙公网安备 33010602011771号