zoukankan      html  css  js  c++  java
  • BZOJ_2724_[Violet 6]蒲公英_分块

    BZOJ_2724_[Violet 6]蒲公英_分块

    Description

    Input

    修正一下

    l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1

    Output

    Sample Input

    6 3
    1 2 3 2 1 2
    1 5
    3 6
    1 5

    Sample Output

    1
    2
    1

    HINT

    n <= 40000, m <= 50000


    对于众数,有一个性质。集合A和集合B的众数,要么是集合A的众数,要么是集合B中出现过的数。

    根据这个性质我们考虑分块。

    先将权值离散化,处理出前缀桶C[i][j]表示1~i块j数出现的次数。

    在处理出mode[i][j]表示i块到j块的众数,这两个都可以在O(nsqrt(n))的时间内处理出来。

    查询时众数来源有两个,所有整块的众数和零散块内出现过的数。

    把零散的每个数统计一下,用桶可以O(1)得到答案。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    using namespace std;
    #define N 40050
    struct A {
        int num,id,v;
    }a[N];
    bool cmp1(const A &x,const A &y){return x.num<y.num;}
    bool cmp2(const A &x,const A &y){return x.id<y.id;}
    int n,m,block,pos[N],L[250],R[250],size,mode[250][250],C[250][N],mp[N],times[250][250],ans;
    int h[N];
    void solve(int l,int r) {
        int p=pos[l],q=pos[r];
        int md=0,i;
        if(p==q||p+1==q) {
            for(i=l;i<=r;i++) {
                h[a[i].v]++;
                if(h[a[i].v]>h[md]||(h[a[i].v]==h[md]&&a[i].v<md))
                    md=a[i].v;
            }
            for(i=l;i<=r;i++) {
                h[a[i].v]=0;
            }
            ans=mp[md];
            return ;
        }
        int nowmode=mode[p+1][q-1],mtimes=times[p+1][q-1];
        h[nowmode]=mtimes;
        int tmp=nowmode;
        //printf("nowmode=%d, mtimes=%d
    ",nowmode,mtimes); 
        for(i=l;i<=R[p];i++) {
            if(!h[a[i].v]) {
                h[a[i].v]=C[q-1][a[i].v]-C[p][a[i].v];
            }
            h[a[i].v]++;
            //printf("a[i].v=%d h[a[i].v]=%d
    ",a[i].v,h[a[i].v]);
            if(h[a[i].v]>mtimes||(h[a[i].v]==mtimes&&a[i].v<nowmode)) {
                mtimes=h[a[i].v]; nowmode=a[i].v;
            }
        }
        for(i=L[q];i<=r;i++) {
            if(!h[a[i].v]) {
                h[a[i].v]=C[q-1][a[i].v]-C[p][a[i].v];
            }
            h[a[i].v]++;
            if(h[a[i].v]>mtimes||(h[a[i].v]==mtimes&&a[i].v<nowmode)) {
                mtimes=h[a[i].v]; nowmode=a[i].v;
            }
        }
        for(i=l;i<=R[p];i++) h[a[i].v]=0;
        for(i=L[q];i<=r;i++) h[a[i].v]=0;
        h[tmp]=0;
        ans=mp[nowmode];
    }
    int main() {
        scanf("%d%d",&n,&m);
        int i,j,k,x,y;
        for(i=1;i<=n;i++) scanf("%d",&a[i].num),a[i].id=i;
        sort(a+1,a+n+1,cmp1); a[0].num=342344354;
        for(i=1,j=0;i<=n;i++) {
            if(a[i].num!=a[i-1].num) j++;
            a[i].v=j;
            mp[j]=a[i].num;
        }
        sort(a+1,a+n+1,cmp2);
        size=sqrt(n);
        block=n/size;
        for(i=1;i<=block;i++) {
            L[i]=R[i-1]+1; R[i]=i*size;
            for(j=L[i];j<=R[i];j++) {
                pos[j]=i;
                /*if(!C[i][a[j].v]) {
                    C[i][a[j].v]=C[i-1][a[j].v];
                }*/
                C[i][a[j].v]++;
            }
            for(j=1;j<=R[i];j++) {
                C[i+1][a[j].v]=C[i][a[j].v];
            }
        }
        if(R[block]!=n) {
            block++; L[block]=R[block-1]+1; R[block]=n;
            for(i=L[block];i<=n;i++) {
                pos[i]=block;
                /*if(!C[block][a[i].v]) {
                    C[block][a[i].v]=C[block-1][a[i].v];
                }*/
                C[block][a[i].v]++;
            }
        }
        for(i=1;i<=block;i++) {
            int md=0;
            for(j=L[i];j<=R[i];j++) {
                if(C[i][a[j].v]-C[i-1][a[j].v]>C[i][md]-C[i-1][md]||(C[i][a[j].v]-C[i-1][a[j].v]==C[i][md]-C[i-1][md]&&a[j].v<md))
                    md=a[j].v;
            }
            mode[i][i]=md; times[i][i]=C[i][md]-C[i-1][md];
            for(j=i+1;j<=block;j++) {
                int md=mode[i][j-1];
                for(k=L[j];k<=R[j];k++) {
                    if(C[j][a[k].v]-C[i-1][a[k].v]>C[j][md]-C[i-1][md]||(C[j][a[k].v]-C[i-1][a[k].v]==C[j][md]-C[i-1][md]&&a[k].v<md))
                        md=a[k].v;
                }
                mode[i][j]=md; times[i][j]=C[j][md]-C[i-1][md];
            }
        }
        //for(i=1;i<=n;i++) printf("i=%d pos[i]=%d
    ",i,pos[i]);
        while(m--) {
            scanf("%d%d",&x,&y);
            x=(x+ans-1)%n+1; y=(y+ans-1)%n+1;
            if(x>y) swap(x,y);
            solve(x,y);
            printf("%d
    ",ans);
        }
    }
    
  • 相关阅读:
    Markdown入门
    JavaScript之bind,call,apply
    CentOS7中禁用IPV6
    How to install Shadow•socks in CentOS7
    How to install OpenBazaar Server in CentOS7
    array_map,array_walk的使用以及区别
    phpstudy 升级mysql 及MySQL服务等问题
    YII2 架构文章链接
    nginx 配置详解(新手必看)
    YII2常用笔记
  • 原文地址:https://www.cnblogs.com/suika/p/8831780.html
Copyright © 2011-2022 走看看