zoukankan      html  css  js  c++  java
  • BZOJ 2724: [Violet 6]蒲公英

    2724: [Violet 6]蒲公英

    Time Limit: 40 Sec  Memory Limit: 512 MB
    Submit: 1633  Solved: 563
    [Submit][Status][Discuss]

    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

    Source

    分析:

    第一次写分块的题目...所以无耻的copyhzwer...

    感觉数据范围不大,可以用分块暴力...

    对于两个整块ab,他们的众数一定存在于mode(a)∪b...脑补一下...

    所以对于一个区间[l,r]的众数一定存在于中间整块的众数和两边不整块的所有数字...

    这样我们如果可以快速查询区间[l,r]的x出现次数就能够解决问题...可以对于每个权值维护一个vector存下来它出现的位置(从大到小),然后二分查询就好了...

    这样预处理的复杂度是n√n的,查询的复杂度是n√nlgn的...

    代码:

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<vector>
     6 #include<map>
     7 //by NeighThorn
     8 using namespace std;
     9 
    10 const int maxn=40000+5,blo=200;
    11 
    12 map<int,int> mp;
    13 
    14 vector<int> v[maxn];
    15 
    16 int n,m,cnt,ans,a[maxn],id[maxn],tot[maxn],val[maxn],f[200+5][200+5];
    17 
    18 inline void init(int x){
    19     int mode=0,maxcnt=0;
    20     memset(tot,0,sizeof(tot));
    21     for(int i=(x-1)*blo+1;i<=n;i++){
    22         tot[a[i]]++;
    23         if(tot[a[i]]>maxcnt||(tot[a[i]]==maxcnt&&val[a[i]]<val[mode]))
    24             mode=a[i],maxcnt=tot[a[i]];
    25         f[x][id[i]]=mode;
    26     }
    27 }
    28 
    29 inline int qrycnt(int l,int r,int x){
    30     return upper_bound(v[x].begin(),v[x].end(),r)-lower_bound(v[x].begin(),v[x].end(),l);
    31 }
    32 
    33 inline int query(int l,int r){
    34     int mode=f[id[l]+1][id[r]-1],maxcnt=qrycnt(l,r,mode);
    35     for(int i=l;i<=min(r,id[l]*blo);i++){
    36         int tmp=qrycnt(l,r,a[i]);
    37         if(tmp>maxcnt||(tmp==maxcnt&&val[a[i]]<val[mode]))
    38             mode=a[i],maxcnt=tmp;
    39     }
    40     if(id[l]!=id[r]){
    41         for(int i=(id[r]-1)*blo+1;i<=r;i++){
    42             int tmp=qrycnt(l,r,a[i]);
    43             if(tmp>maxcnt||(tmp==maxcnt&&val[a[i]]<val[mode]))
    44                 mode=a[i],maxcnt=tmp;
    45         }
    46     }
    47     return mode;
    48 }
    49 
    50 signed main(void){
    51     ans=cnt=0;
    52     scanf("%d%d",&n,&m);
    53     for(int i=1;i<=n;i++){
    54         scanf("%d",&a[i]);
    55         if(mp.find(a[i])==mp.end())
    56             mp[a[i]]=++cnt,val[cnt]=a[i];
    57         a[i]=mp[a[i]];v[a[i]].push_back(i);
    58     }
    59     for(int i=1;i<=n;i++)
    60         id[i]=(i-1)/blo+1;
    61     for(int i=1;i<=id[n];i++)
    62         init(i);
    63     for(int i=1,x,y;i<=m;i++){
    64         scanf("%d%d",&x,&y);
    65         x=(x+ans-1)%n+1,y=(y+ans-1)%n+1;
    66         if(x>y)
    67             swap(x,y);
    68         ans=val[query(x,y)];
    69         printf("%d
    ",ans);
    70     }
    71     return 0;
    72 }
    View Code

    by NeighThorn

  • 相关阅读:
    文件路径选择中的三态逻辑
    .net版本号
    使用MSBuild编译vs多个解决方案
    CEF截图
    使用SharpZIpLib写的压缩解压操作类
    软件试用期设置
    list转datatable
    excel 导入
    网站登录简单验证码
    UEditor编辑器
  • 原文地址:https://www.cnblogs.com/neighthorn/p/6193590.html
Copyright © 2011-2022 走看看