BZOJ 2724: [Violet 6]蒲公英

Posted NeighThorn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\\n",ans);
70     }
71     return 0;
72 }
View Code

by NeighThorn

以上是关于BZOJ 2724: [Violet 6]蒲公英的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 2724 2724: [Violet 6]蒲公英 (区间众数不带修改版本)

BZOJ2724[Violet 6]蒲公英 分块+二分

[bzoj2724] [Violet 6]蒲公英

bzoj 2724: [Violet 6]蒲公英

BZOJ2724: [Violet 6]蒲公英

BZOJ2724: [Violet 6]蒲公英