luogu 数列找不同-莫队

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
");
}