zoukankan      html  css  js  c++  java
  • AcWing249 蒲公英(分块)

    一道经典的分块例题,因为我们通过观察可知,区间众数要不就是中间所有块上的答案,要不就是两边小块上出现过的值

    因此我们可以分块处理,只要预处理块与块之间的答案即可,因为本题没有修改操作

    另外这题比较卡常,块的大小要先算好,不过也有复杂度更低的算法

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<string>
    #include<map>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const int N=1e6+10;
    const int mod=1e9+7;
    vector<int> g[N];
    int d[2001][2001];
    int c[N],a[N];
    int n,m;
    int block;
    int cnt[N];
    void init(){
        int l,r;
        for(l=1;l<=n;l+=block){
            int res=0;
            memset(cnt,0,sizeof cnt);
            for(r=l;r<=n;r++){
                cnt[a[r]]++;
                if(cnt[a[r]]>cnt[res]||cnt[a[r]]==cnt[res]&&a[r]<res)
                res=a[r];
                if(r%block==0||r==n)
                d[(l-1)/block+1][(r-1)/block+1]=res;
            }
        }
    }
    int find(int l,int r,int x){
        return upper_bound(g[x].begin(),g[x].end(),r)-lower_bound(g[x].begin(),g[x].end(),l);
    }
    int query(int l, int r){
        int ans = 0;
        int B=block;
        int idl = (l-1)/B+1, idr = (r-1)/B+1;
        if(idl+1 < idr) ans = d[idl+1][idr-1];
        int n = find(l,r,ans), n1;
        if(idl==idr){
            for(int i=l;i<=r;i++){
                n1 = find(l,r,a[i]);
                if(n < n1 || n == n1 && a[i] < ans) ans = a[i], n = n1;
            }
        }
        else{
            for(int i=l;i<=idl*B;i++){
                n1 = find(l,r,a[i]);
                if(n < n1 || n == n1 && a[i] < ans) ans = a[i], n = n1;
            }
            for(int i=(idr-1)*B+1;i<=r;i++){
                n1 = find(l,r,a[i]);
                if(n < n1 || n == n1 && a[i] < ans) ans = a[i], n = n1;
            }
        }
        return c[ans];
    }
    
    int main(){
        cin>>n>>m;
        int i;
        block=max(1,(int)(n/sqrt(m*log2(n))));
        for(i=1;i<=n;i++){
            scanf("%d",&a[i]);
            c[i]=a[i];
        }
        sort(c+1,c+1+n);
        for(i=1;i<=n;i++){
            a[i]=lower_bound(c+1,c+1+n,a[i])-c;
            g[a[i]].push_back(i);
        }
        init();
        int last=0;
        int l,r;
        while(m--){
            scanf("%d%d",&l,&r);
            l = (l+last-1)%n + 1;
            r = (r+last-1)%n + 1;
            if(l>r)
                swap(l,r);
            last=query(l,r);
            printf("%d
    ",last);
        }
    }
    View Code
  • 相关阅读:
    关于数据仓库的数据模型的思考
    西影寺的由来
    机器能像人一样思考吗?人工智能(一)机器学习和神经网络
    手机摄影超越单反?触手可及的AI让每个人成为专业摄影师!
    Flower
    Backpropagation算法 (转
    Spring Data JPA:解析CriteriaQuery
    Spring Data JPA:解析CriteriaBuilder
    Spring Data JPA:解析JpaSpecificationExecutor & Specification
    Spring Data JPA:解析SimpleJpaRepository
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12765131.html
Copyright © 2011-2022 走看看