zoukankan      html  css  js  c++  java
  • bzoj2724: [Violet 6]蒲公英 分块 区间众数 论algorithm与vector的正确打开方式

    这个,要处理各个数的话得先离散,我用的桶。

    我们先把每个块里的和每个块区间的众数找出来,那么在查询的时候,可能成为[l,r]区间的众数的数只有中间区间的众数和两边的数。

    证明:若不是这里的数连区间的众数都达不到。

    我已开始把某个离散后的值当成了坐标,调了好久.......

    #include<cstdio>
    #include<cmath>
    #include<vector>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int b[40010],a[40010],n,m,lon,pos[40010],t,p[40010],back[40010],num[40010],f[210][210],sz;
    int cmp(const int x,const int y)
    {
        if(b[x]<b[y])return 1;
        if(b[x]==b[y]&&x<y)return 1;
        return 0;
    }
    vector<int> place[40010];
    inline void do_it(int x)
    {
        memset(num,0,sizeof(num));
        int who=0,how=0;
        for(int i=(x-1)*lon+1;i<=n;i++)
        {
          num[a[i]]++;
          if(num[a[i]]>how||(num[a[i]]==how&&back[a[i]]<back[who]))
            who=a[i],how=num[a[i]];
          f[x][pos[i]]=who;
        }
    }
    inline void Init()
    {
        scanf("%d%d",&n,&m);
        lon=(int)sqrt(n+0.5);
        for(int i=1;i<=n;i++)
        {
          scanf("%d",&b[i]);
          p[i]=i;
          pos[i]=(i-1)/lon+1;
        }
        sort(p+1,p+n+1,cmp);
        for(int i=1;i<=n;i++)
        {
          if(b[p[i]]!=b[p[i-1]])
          {
            a[p[i]]=++sz;
            back[sz]=b[p[i]];
          }
          else
            a[p[i]]=sz;
          place[sz].push_back(p[i]);
        }
        t=pos[n];
        for(int i=1;i<=t;i++)do_it(i);
    }
    inline int query(int l,int r,int x)
    {
        return upper_bound(place[x].begin(),place[x].end(),r)-lower_bound(place[x].begin(),place[x].end(),l);
    }
    inline int Min(int x,int y){return x<y?x:y;}
    inline int work(int l,int r)
    {
        int z=pos[l]+1,y=pos[r]-1;
        int who=f[z][y],how=query(l,r,who);
        int zzh=(z-1)*lon;
        zzh=Min(zzh,r);
        for(int i=l;i<=zzh;i++)
        {
          int x=query(l,r,a[i]);
          if(x>how||(x==how&&a[i]<who))
             who=a[i],how=x;
        }
        if(pos[l]!=pos[r])
        {
            zzh=(y*lon)+1;
            for(int i=zzh;i<=r;i++)
            {
              int x=query(l,r,a[i]);
              if(x>how||(x==how&&a[i]<who))
                 who=a[i],how=x;
            }
        }
        return back[who];
    }
    int main()
    {
        Init();
        int k=0;
        for(int i=1;i<=m;i++)
        {
           int x,y;
           scanf("%d%d",&x,&y);
           x=(x+k-1)%n+1;
           y=(y+k-1)%n+1;
           if(x>y)x^=y^=x^=y;
           k=work(x,y);
           printf("%d
    ",k);
        }
        return 0;
    }
    苟利国家生死以, 岂因祸福避趋之。
  • 相关阅读:
    [C++] split string by string
    工作三个月心得经验
    Ubuntu Command-Line: Enable Unlimited Scrolling in the Terminal
    What is the PPA and How to do with it ?
    WCF vs ASMX WebService
    The ShortCuts in the ADT (to be continued)
    when does the View.ondraw method get called
    Browsing Storage Resources with Server Explorer
    Get start with Android development
    C++ Frequently asking question
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7006920.html
Copyright © 2011-2022 走看看