题目描述
亲爱的哥哥:
你在那个城市里面过得好吗?
我在家里面最近很开心呢。昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被它杀掉了。我觉得把那么可怕的怪物召唤出来的那个坏蛋也很坏呢。不过奶奶说他是很难受的时候才做出这样的事的……
最近村子里长出了一大片一大片的蒲公英。一刮风,这些蒲公英就能飘到好远的地方了呢。我觉得要是它们能飘到那个城市里面,让哥哥看看就好了呢!
哥哥你要快点回来哦!
爱你的妹妹 Violet
Azure 读完这封信之后微笑了一下。
“蒲公英吗……”
在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关。
为了简化起见,我们把所有的蒲公英看成一个长度为 n 的序列 (),其中 为一个正整数,表示第 i 棵蒲公英的种类编号。
而每次询问一个区间[l, r],你需要回答区间里出现次数最多的是哪种蒲公英,如果有若干种蒲公英出现次数相同,则输出种类编号最小的那个。
注意,你的算法必须是在线的。
输入格式
第一行两个整数 n, m,表示有 n 株蒲公英,m 次询问。
接下来一行 n 个空格分隔的整数 ,表示蒲公英的种类。
再接下来 m 行每行两个整数 ,我们令上次询问的结果为 x(如果这是第一次询问,则 x = 0)。
令 ,如果 l > r,则交换 l, r。
最终的询问区间为[l, r]。
输出格式
输出 m 行。每行一个整数,表示每次询问的结果。
样例
样例输入
6 3
1 2 3 2 1 2
1 5
3 6
1 5
样例输出
1
2
1
目前是T的
点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map<int,int> push;
map<int,int> back;
int n,m;
int len;
int from,to;
ll t[60000];
ll a[60000];
int f[500][60000];
int l[60000],r[60000];
int vis[60000];
ll num[60000];
void div(){
int sq=sqrt(n);
for(int i=1;i<=sq;i++){
l[i]=sq*(i-1)+1;
r[i]=sq*i;
}
if(r[sq]<n){
sq++;
l[sq]=r[sq-1]+1;
r[sq]=n;
}
for(int i=1;i<=sq;i++){
for(int j=l[i];j<=r[i];j++){
vis[j]=i;
f[i][push[a[j]]]++;
}
}
}
int check(int x,int y){
memset(num,0,sizeof(num));
int ans=0;ll last=0x7ffffffff;
int p=vis[x],q=vis[y];
if(p==q){
for(int i=x;i<=y;i++){
num[push[a[i]]]++;
}
for(int i=x;i<=y;i++){
if((ans<num[push[a[i]]])||(ans==num[push[a[i]]]&&last>a[i])){
ans=num[push[a[i]]];
last=a[i];
}
}
}
else{
for(int i=x;i<=r[p];i++){
num[push[a[i]]]++;
}
for(int i=p+1;i<q;i++){
for(int j=1;j<=len;j++){
num[j]+=f[i][j];
}
}
for(int i=l[q];i<=y;i++){
num[push[a[i]]]++;
}
for(int i=1;i<=len;i++){
if((ans<num[i])||(ans==num[i]&&last>back[i])){
ans=num[i];
last=back[i];
}
}
}
return last;
}
int main(){
int x=0;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];t[i]=a[i];
}
sort(t+1,t+1+n);
len=unique(t+1,t+1+n)-t-1;
for(int i=1;i<=len;i++){
push[t[i]]=i;
back[i]=t[i];
}
div();
for(int i=1;i<=m;i++){
cin>>from>>to;
from=(from+x-1)%n+1;
to=(to+x-1)%n+1;
if(from>to) swap(from,to);
cout<<check(from,to)<<endl;
x=check(from,to);
}
}