zoukankan      html  css  js  c++  java
  • P4168 [Violet]蒲公英

    P4168 [Violet]蒲公英

    分块

    吸了氧气才过

    强制在线区间众数,具体见hzwer的解题报告(右转Baidu)

    先把数字离散化

    然后对于每个数字开个动态数组存出现的位置

    每次对完整块的众数和不完整块的所有数在动态数组中进行查询,答案必定在它们之中

    code:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    #include<map>
    #include<cctype>
    using namespace std;
    inline int Int(){
        char c=getchar(); int x=0;
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
        return x;
    }
    inline int min(int &a,int &b) {return a<b ?a:b;}
    int n,m,ans,mxd,cnt,_blo,blo[40002],a[40002],f[210][210],mp[40002],ct[40002];
    vector <int> v[40002];
    map <int,int> Map;
    inline void pre(int x){ //预处理整块的区间众数
        memset(ct,0,sizeof(ct)); int mx=0,t=0;
        for(int i=(x-1)*_blo+1;i<=n;++i){
            ++ct[a[i]];
            if(ct[a[i]]>mx||(mx==ct[a[i]]&&mp[a[i]]<mp[t])) t=a[i],mx=ct[a[i]];
            f[x][blo[i]]=t; //第x块到blo[i]块之间的众数
        }
    }
    inline int find(int l,int r,int k){ //区间内出现的次数
        return upper_bound(v[k].begin(),v[k].end(),r)-lower_bound(v[k].begin(),v[k].end(),l);
    }
    inline void query(int l,int r){
        ans=f[blo[l]+1][blo[r]-1];
        mxd=find(l,r,ans); //完整块的众数
        for(int i=min(blo[l]*_blo,r);i>=l;--i){ //对于不完整的块,对所有数暴力查询
            int t=find(l,r,a[i]);
            if(t>mxd||(t==mxd&&mp[a[i]]<mp[ans])) mxd=t,ans=a[i];
        }
        if(blo[l]==blo[r]) return ;
        for(int i=(blo[r]-1)*_blo+1;i<=r;++i){
            int t=find(l,r,a[i]);
            if(t>mxd||(t==mxd&&mp[a[i]]<mp[ans])) mxd=t,ans=a[i];
        }
    }
    int main(){
        n=Int(); m=Int(); _blo=sqrt(n); int q1,q2;
        for(int i=1;i<=n;++i){
            a[i]=Int();
            if(!Map[a[i]]) Map[a[i]]=++cnt,mp[cnt]=a[i];
            a[i]=Map[a[i]]; //离散化
            v[a[i]].push_back(i);
            blo[i]=(i-1)/_blo+1;
        }
        for(int i=1;i<=blo[n];++i) pre(i);
        for(int i=1;i<=m;++i){
            q1=Int(); q2=Int();
            q1=(q1+ans-1)%n+1,q2=(q2+ans-1)%n+1;
            if(q1>q2) swap(q1,q2);
            query(q1,q2); ans=mp[ans];
            printf("%d
    ",ans);
        } return 0;
    }
  • 相关阅读:
    JavaScript Location对象
    JavaScript History 对象
    JavaScript Navigator 对象
    C#实现windows系统重启、关机
    JavaScript ObjectURL | URL.createObjectURL和URL.revokeObjectURL
    依赖注入在 dotnet core 中实现与使用:4. 集成 Autofac
    Raid5的搭建、测试、取消
    Linux磁盘阵列(RAID)概述与实战
    Zookeeper超级用户使用案例:How to remove ACL protected ZK Node
    Kafka 权限管理实战(最全整理)
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/9652989.html
Copyright © 2011-2022 走看看