• 数列找不同


    题目描述

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

    输入格式

    第1 行,2 个整数N,QN,Q

    第2 行,N 个整数A_{Li} ,A_{Li+1},cdots,A_{Ri}ALi,ALi+1,,ARi

    Q 行,每行2 个整数L_i,R_iLi,Ri

    输出格式

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

    输入输出样例

    输入 #1
    4 2
    1 2 3 2
    1 3
    2 4
    输出 #1
    Yes
    No

    说明/提示

    • 对于50% 的数据,N,Q le 10^3N,Q103

    • 对于100% 的数据,1 le N,Q le 10^5, 1 le A_i le N, 1 le L_i le R_i le N1N,Q105,1AiN,1LiRiN

    我们想,因为每次查询是离线的,所以我们先给每次的查询排一个序。

    排序的方法是

    分块。

    我们把所有的元素分成多个块(即分块)。分了块跑的会更快。再按照右端点从小到大,左端点块编号相同按右端点从小到大。

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    
    const int maxn=100010;
    
    inline int read(){
        int s=0,w=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-'){
                w=-1;
            }
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            s=s*10+ch-'0';
            ch=getchar();
        }
        return s*w;
    }
    
    int n,m,hhh,ans=0,kkksc03,kkksc04,cnt[maxn],a[maxn],i;
    
    bool anb[maxn];
    
    struct node{
        int l,r,p;
    }q[maxn];
    
    bool cmp(const node x,const node y){
        return (x.l/hhh)==(y.l/hhh)?x.r<y.r:x.l<y.l;
    }
    
    void add(int position){
        if((++cnt[a[position]])==1){
            ++ans;
        }
    }
    
    void remove(int position){
        if((--cnt[a[position]])==0){
            --ans;
        }
    }
    
    int main(){
        n=read();
        m=read();
        hhh=sqrt(n);
        for(i=1;i<=n;i++){
            a[i]=read();
        }
        for(i=1;i<=m;i++){
            q[i].l=read();
            q[i].r=read();
            q[i].p=i;
        }
        sort(q+1,q+1+m,cmp);
        for(i=1;i<=m;i++){
            int L=q[i].l,R=q[i].r;
            while(kkksc03<L){
                remove(kkksc03++);
            }
            while(kkksc03>L){
                add(--kkksc03);
            }
            while(kkksc04<R){
                add(++kkksc04);
            }
            while(kkksc04>R){
                remove(kkksc04--);
            }
            if(ans==(R-L+1)){
                anb[q[i].p]=1;
            }
        }
        for(i=1;i<=m;i++){
            if(anb[i]==1){
                printf("Yes
    ");
            }
            else{
                printf("No
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    202103226-1 编程作业
    MSF原则
    介绍
    4 20210412-1 原型设计作业
    案例分析作业
    第二次编程
    阅读任务
    自我介绍
    案例分析作业
    阅读任务
  • 原文地址:https://www.cnblogs.com/hrj1/p/11235037.html
Copyright © 2020-2023  润新知