P3901 数列找不同(简单莫队)
莫队入门题目,区间不相同数查询
应该用线段树也能做,但是不知道该维护什么。
一篇很好的题解:
https://www.cnblogs.com/MisakaAzusa/p/8684319.html
莫队算法主要解决的问题:
莫队算法是用来处理一类无修改的离线区间询问问题。
莫队算法的思想:
1、分块and排序,使相邻的查询区间尽量接近,curL和curR两个指针移动的距离尽量少
2、桶排查询
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=1e5+5; 5 6 int n,m,blo; 7 int Ans=0,curL,curR,cnt[maxn]; 8 //the initial values of curL and curR both are 0 9 struct node{ 10 int l,r,q; 11 }Q[maxn]; 12 int a[maxn]; 13 int ans[maxn]; 14 15 bool cmp(node x,node y){ 16 return (x.l/blo)==(y.l/blo) ? x.r<y.r : x.l<y.l; 17 } 18 19 void add(int pos){ 20 if((++cnt[a[pos]])==1) ++Ans; 21 } 22 23 void del(int pos){ 24 if((--cnt[a[pos]])==0) --Ans; 25 } 26 27 28 int main(){ 29 cin>>n>>m;blo=sqrt(n); 30 for(int i=1;i<=n;i++) 31 cin>>a[i]; 32 for(int i=1;i<=m;i++){ 33 cin>>Q[i].l>>Q[i].r; 34 Q[i].q=i; 35 } 36 37 sort(Q+1,Q+1+m,cmp); 38 39 for(int i=1;i<=m;i++){ 40 int L=Q[i].l;int R=Q[i].r; 41 while(curL<L) del(curL++); 42 while(curL>L) add(--curL); 43 while(curR<R) add(++curR); 44 while(curR>R) del(curR--); 45 if(Ans==(R-L+1)) 46 ans[Q[i].q]=1; 47 } 48 49 for(int i=1;i<=m;i++) 50 { 51 if(ans[i]==1) cout <<"Yes\n"; 52 else cout <<"No\n"; 53 } 54 return 0; 55 }