• LUOGU P3901 数列找不同


    传送门

    解题思路

    莫队第一题,离线神器。先分块,然后按左端点的块为第一关键字,右端点为第二关键字排序,然后类似暴力的统计答案。时间复杂度O(nsqrt(n)) (不会证。。。)

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    
    using namespace std;
    const int MAXN = 1e5+5;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {f=ch=='-'?-1:1;ch=getchar();}
        while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return x*f;
    }
    
    int n,m,siz,num,L,R,now;
    int a[MAXN],bl[MAXN];
    int b[MAXN],ans[MAXN];
    
    struct Ask{
        int l,r,id;
    }q[MAXN];
    
    inline bool cmp(Ask A,Ask B){
        if(bl[A.l]==bl[B.l]) return A.r<B.r;
        return bl[A.l]<bl[B.l];
    }
    
    inline bool cmp2(Ask A,Ask B){
        return A.id<B.id;
    }
    
    int main(){
        n=rd();m=rd();
        siz=sqrt(n)+1;num=n/siz;if(n%siz) num++;
        for(register int i=1;i<=n;i++) {
            a[i]=rd();
            bl[i]=(i-1)/siz+1;
        }
        for(register int i=1;i<=m;i++)  q[i].l=rd(),q[i].r=rd(),q[i].id=i;
        sort(q+1,q+1+m,cmp);
        L=0,R=0;now=0;
        for(register int i=1;i<=m;i++) {
            while(R<q[i].r) {R++;if(!b[a[R]]) now++;b[a[R]]++;}
            while(R>q[i].r){b[a[R]]--;if(!b[a[R]]) now--;R--;}
            while(L<q[i].l){b[a[L]]--;if(!b[a[L]]) now--;L++;}
            while(L>q[i].l){L--;if(!b[a[L]]) now++;b[a[L]]++;}      
            if(now==q[i].r-q[i].l+1) ans[q[i].id]=1;
        }
        sort(q+1,q+1+m,cmp2);
        for(register int i=1;i<=m;i++)
            puts(ans[i]==1?"Yes":"No");
        return 0;
    }
  • 相关阅读:
    String类之indexOf--->查找某字对应的位置
    5、文件过滤器
    String类之endsWith方法--->检测该字符串以xx为结尾
    for循环
    java-成员方法/变量、类方法/变量等区别
    4、File类之获取方法
    3、File类之创建、删除、重命名、判断方法
    2、创建File类对象
    Java 实现Redis客户端,服务端
    Phoenix踩坑填坑记录
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9676883.html
Copyright © 2020-2023  润新知