zoukankan      html  css  js  c++  java
  • 【题解】P4137 Rmq Problem(莫队)

    【题解】P4137 Rmq Problem(莫队)

    其实这道题根本就不用离散化!

    因为显然有(mex)值是(le 2 imes 10^5)的,所以对于大于(2 imes 10^5)的数我们可以忽略。

    然后直接莫队算就是的,开一个(2e5)的桶

    • 若一个比答案小的值的桶为(0)了:答案更新为它
    • 若这个(mex)的桶突然有值了:暴力枚举答案变大,第一个桶里没值的就是答案,更新。

    有小伙伴会问,这复杂度不上天了?其实不然。移动(ans)的总复杂度(好像)是(O(nsqrt n))的,因为:

    • 当区间长度增大时,(ans)的移动是均摊(O( ext{区间长度}))的(最坏情况(好像)是加进来的数就变成了一个递增序列)。

    • 当区间减小时,(ans)是直接更新的。所以(ans)指针的移动和(L,R)指针的移动次数是同级的。

    由于莫队中,区间减小增大不是交替的(不存在(L)动一次交替然后(R)动一次)(都是一个动完再动另外一个),所以最终复杂度(O(nsqrt n)),实际上(貌似)吊打(O(n log n))

    //@winlere
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    
    using namespace std;  typedef long long ll;
    inline int qr(){
          register int ret=0,f=0;
          register char c=getchar();
          while(c<48||c>57)f|=c==45,c=getchar();
          while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
          return f?-ret:ret;
    }
    
    const int maxn=2e5+5;
    int be[maxn];
    int data[maxn];
    int s[maxn];
    int n,N,ans,m;
    struct Q{
          int l,r,id;
          Q(){l=r=id=0;}
          Q(const int&a,const int&b,const int&c){l=a;r=b;id=c;}
          inline bool operator <(const Q&a)const{return be[l]==be[a.l]?(be[l]&1?r<a.r:r>a.r):(l<a.l);}
    }q[maxn];
    
    inline void add(const int&pos,const int&tag){
          if(data[pos]>maxn) return;
          s[data[pos]]+=tag;
          const int k=s[data[pos]];
          if(k==0&&ans> data[pos]) ans=data[pos];
          if(k==1&&ans==data[pos]) 
    	    while(++ans) if(!s[ans]) return;
    }
    
    int main(){
          n=qr(),m=qr();
          N=sqrt(n)+1;
          for(register int t=1;t<=n;++t) be[t]=(t-1)/N+1;
          for(register int t=1;t<=n;++t) data[t]=qr();
          for(register int t=1,t1,t2;t<=m;++t) t1=qr(),t2=qr(),q[t]=Q(t1,t2,t);
          sort(q+1,q+m+1);
          register int L=1,R=0;
          for(register int t=1;t<=m;++t){
    	    while(L<q[t].l) add(L++,-1);
    	    while(L>q[t].l) add(--L, 1);
    	    while(R<q[t].r) add(++R, 1);
    	    while(R>q[t].r) add(R--,-1);
    	    be[q[t].id]=ans;
          }
          for(register int t=1;t<=m;++t) printf("%d
    ",be[t]);
          return 0;
    }
    
    
  • 相关阅读:
    【Vuejs】509- vue-loader工作原理
    【JS】508- MVVM原理介绍
    【Webpack】507- 基于Tree-shaking的多平台Web代码打包实践
    【TS】506- TypeScript 交叉类型
    【WebSocket】505- WebSocket 入门到精通
    【语雀知识库分享】HTTP面试宝典
    【JS】504- HTML5 之跨域通讯(postMessage)
    jQuery 选择器
    JQuery简介
    什么是JDBC的最佳实践?
  • 原文地址:https://www.cnblogs.com/winlere/p/11432222.html
Copyright © 2011-2022 走看看