zoukankan      html  css  js  c++  java
  • 蒲公英

    题意

    求一段区间的众数,相同次数选小的那个。强制在线

    对于 100% 的数据,保证1n40000,1m50000,1ai109

    题解

    如果不要求强制在线就可以用回滚莫队解决。

    那在线怎么做?还是考虑分块,预处理出第i块到第j块这段区间的桶和众数。

    对于一段区间查询[l,r],分成3部分,(l,L)和(R,r)两个不足一整段的部分和中间的整块区间[L,R]。

    每次查询就在预处理的[pos[L],pos[R]]基础上统计答案,最后再撤销即可。

    算法事件复杂度(NS2+MN/S),空间复杂度(NS2),设N,M为相同数量级,那么S=N1/3时复杂度在(N5/3),S为块的个数

    注意离散化

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn=40005;
    int n,m;
    int a[maxn],b[maxn];
    int size,pos[maxn];
    int cnt[40][40][maxn],nowans[40][40];//第i块到第j块的各数的个数和众数 
    int ans;
    
    template<class T>inline void read(T &x){
        x=0;char ch=getchar();
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    }
    
    void nice(int i,int j,int cx[],int &nowans){//预处理,nowans必须加&,否则不能改变 
        int l=size*(i-1)+1,r=min(n,size*j);
        for(int k=l;k<=r;k++){
          cx[a[k]]++;
          if(cx[nowans]<cx[a[k]]) nowans=a[k];
          else if(cx[nowans]==cx[a[k]]&&a[k]<nowans) nowans=a[k];
        }
    }  
    
    int good[maxn];
    
    void sto324(int l,int r){//暴力 
        for(int i=l;i<=r;i++)
         good[a[i]]=0;
        for(int i=l;i<=r;i++){
            good[a[i]]++;
            if(good[a[i]]>good[ans]) ans=a[i];
            else if(good[a[i]]==good[ans]&&a[i]<ans) ans=a[i];
        }
        return ;
    }
    
    void get_it(int l,int r){
        ans=0;
        if(pos[r]-pos[l]<=1){sto324(l,r);return ;}//在同一块或相邻块,保证[L,R]成立 
        int L=pos[l]+1,R=pos[r]-1;
        ans=nowans[L][R];
        for(int i=l;pos[i]==pos[l];i++){
            cnt[L][R][a[i]]++;
            if(cnt[L][R][a[i]]>cnt[L][R][ans]) ans=a[i];
            else if(cnt[L][R][a[i]]==cnt[L][R][ans]&&a[i]<ans) ans=a[i];
        }
        for(int i=r;pos[i]==pos[r];i--){
            cnt[L][R][a[i]]++;
            if(cnt[L][R][a[i]]>cnt[L][R][ans]) ans=a[i];
            else if(cnt[L][R][a[i]]==cnt[L][R][ans]&&a[i]<ans) ans=a[i];
        }
        for(int i=l;pos[i]==pos[l];i++) cnt[L][R][a[i]]--;
        for(int i=r;pos[i]==pos[r];i--) cnt[L][R][a[i]]--;//撤销操作 
    }
    
    int main(){
        read(n);read(m);
        size=(int)pow(n,2.0/3);
        for(int i=1;i<=n;i++){
            read(a[i]);
            b[i]=a[i];
            pos[i]=(i-1)/size+1;
        }
        sort(b+1,b+n+1);
        int tot=unique(b+1,b+n+1)-b-1;
        for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+tot+1,a[i])-b;
        for(int i=1;i<=pos[n];i++)
         for(int j=i;j<=pos[n];j++)
          nice(i,j,cnt[i][j],nowans[i][j]);
        for(int i=1;i<=m;i++){
            int l,r;
            read(l);read(r);
            l=(l+b[ans]-1)%n+1;
            r=(r+b[ans]-1)%n+1;
            if(l>r) swap(l,r);
            //printf("%d %d
    ",l,r);
            get_it(l,r);
            printf("%d
    ",b[ans]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    struts1:(Struts)ActionForm类及表单数据验证
    前端基础
    JavaScript 开发进阶:理解 JavaScript 作用域和作用域链
    vue+webpack一些知识
    gulp简单使用小记
    如何在Github Pages搭建自己写的页面?
    十大名茶
    中国六大茶类
    从零开始用gulp
    15 个有趣的 JavaScript 与 CSS 库
  • 原文地址:https://www.cnblogs.com/sto324/p/11240104.html
Copyright © 2011-2022 走看看