刷题洛谷 P3901 数列找不同

Posted oyiya

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了刷题洛谷 P3901 数列找不同相关的知识,希望对你有一定的参考价值。

题目描述

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

输入输出格式

输入格式:

第1 行,2 个整数 \(N,Q\)

第2 行,N 个整数 \(A_{Li} ,A_{Li+1},\cdots,A_{Ri}\)?

Q 行,每行2 个整数 \(L_i,R_i\)?

输出格式:

对每个询问输出一行,“Yes” 或者“No”

输入输出样例

输入样例#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\)

题解

当做莫队裸题做了,加数和删数的时候只要判之前或之后是不是一来更改某一段的贡献
(这题还可以 \(O(n)\) 做,而且很好写,不过为了写个模板,就没去写了)

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=100000+10;
int n,q,A[MAXN],unit,Be[MAXN],cnt[MAXN],sum,ans[MAXN];
struct node{
    int l,r,id;
    inline bool operator < (const node &A) const {
        return Be[l]==Be[A.l]?r<A.r:l<A.l;
    };
};
node query[MAXN];
template<typename T> inline void read(T &x)
{
    T data=0,w=1;
    char ch=0;
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')w=-1,ch=getchar();
    while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
    if(x<0)putchar('-'),x=-x;
    if(x>9)write(x/10);
    putchar(x%10+'0');
    if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void add(int x)
{
    if((cnt[x]++)==1)sum++;
}
inline void del(int x)
{
    if((--cnt[x])==1)sum--;
}
int main()
{
    read(n);read(q);
    unit=std::sqrt(n);
    for(register int i=1;i<=n;++i)read(A[i]),Be[i]=i/unit+1;
    for(register int i=1;i<=q;++i)
    {
        read(query[i].l),read(query[i].r);
        query[i].id=i;
    }
    std::sort(query+1,query+q+1);
    int l=1,r=0;
    for(register int i=1;i<=q;++i)
    {
        while(l<query[i].l)del(A[l++]);
        while(l>query[i].l)add(A[--l]);
        while(r<query[i].r)add(A[++r]);
        while(r>query[i].r)del(A[r--]);
        ans[query[i].id]=sum;
    }
    for(register int i=1;i<=q;++i)puts(ans[i]?"No":"Yes");
    return 0;
}

以上是关于刷题洛谷 P3901 数列找不同的主要内容,如果未能解决你的问题,请参考以下文章

P3901 数列找不同

luogu P3901 数列找不同 题解

题解Luogu P3901 数列找不同

刷题洛谷 P3455 [POI2007]ZAP-Queries

刷题洛谷 P1115 最大子段和

刷题洛谷 P3807 模板卢卡斯定理