https://www.luogu.org/problemnew/show/P3901
了解过莫队的人应该都清楚,莫队是一个优化的暴力,可以在相对暴力比较优的时间中,求出一段序列内的某些性质(例:数字的种类)
那么这道题就明显是一道模板题了,在l,r(左右段点)移动的过程中,记录数字的种类,若种类数等于R-L+1,那么表明没有重复。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #define N int(1e5+2) #define M int(1e5+2) using namespace std; struct ahah{ int L,R,p,f; }ask[N]; int answer,n,q,a[N],cnt[N],ans[N],k; bool cmp(ahah a,ahah b){ return a.p<b.p; } bool comp(ahah a,ahah b){ return a.L/k==b.L/k?a.R<b.R:a.L<b.L; } void remove(int pos){ if(--cnt[a[pos]]==0)answer--; } void add(int pos){ if(++cnt[a[pos]]==1)answer++; } int main() { scanf("%d%d",&n,&q); k=sqrt(n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<=q;i++)scanf("%d%d",&ask[i].L,&ask[i].R),ask[i].p=i; sort(ask+1,ask+1+q,comp); int curl=0,curr=0; for(int i=1;i<=q;i++) { int L=ask[i].L,R=ask[i].R; while(curl<L)remove(curl++); while(curl>L)add(--curl); while(curr<R)add(++curr); while(curr>R)remove(curr--); answer==R-L+1?ans[ask[i].p]=1:ans[ask[i].p]=0; } for(int i=1;i<=q;i++)ans[i]==1?printf("Yes "):printf("No "); }