万年前的题解,可能会体验不好,慎看。
1.题意
因为出题人语死早,原题意比较毒瘤,所以这里整个舒服点的题意:
静态询问区间众数对应的该众数个数
(至于为什么已经有daolao给出证明了)
(注意答案要取负)
2.思路
由于是静态问题,且询问的是区间众数,所以很容易我们可以想到用莫队来解决这个问题
在本题中,莫队对应的基础操作很容易可以想到:
1.维护当前序列中每个数a[i]的出现次数cnt[a[i]]
2.维护当前的众数有多少个
所以移动区间的时候判断讨论一下就可以了
(注意要离散化 (因为a[i]为1e9) )
3.代码
#include<bits/stdc++.h>
using namespace std;
const int N=10000005,M=10000005;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-'){f=-1;}ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int a[N],pos[N],n,m,ANS[N],ans=1,cnt[N],num[N],A[N];
struct node{
int l,r,id;
}q[N];
inline bool cmp(node x,node y){
if(pos[x.l]==pos[y.l]) return x.r<y.r;
return pos[x.l]<pos[y.l];
}
inline void update(int id,int f){
if(f==1){
num[cnt[a[id]]]--;
num[cnt[a[id]]+1]++;
cnt[a[id]]++;
if(cnt[a[id]]>ans) ans=cnt[a[id]];
}
else{
num[cnt[a[id]]]--;
if(num[ans]==0) ans--;
num[cnt[a[id]]-1]++;
cnt[a[id]]--;
}
return ;
}
int main(){
n=read(),m=read();
int op=sqrt(n);
for(int i=1;i<=n;i++){
A[i]=read();
a[i]=A[i];
pos[i]=i/op;
}
sort(A+1,A+n+1);
int nn=unique(A+1,A+n+1)-A-1;
for(int i=1;i<=n;i++) a[i]=lower_bound(A+1,A+nn+1,a[i])-A;
for(int i=1;i<=m;i++){
q[i].l=read(),q[i].r=read(),q[i].id=i;
}
sort(q+1,q+m+1,cmp);
for(int i=1,l=1,r=0;i<=m;i++){
while(l<q[i].l) update(l++,-1);
while(l>q[i].l) update(--l,1);
while(r<q[i].r) update(++r,1);
while(r>q[i].r) update(r--,-1);
ANS[q[i].id]=ans;
}
for(int i=1;i<=m;i++) printf("%d
",(-1)*ANS[i]);
return 0;
}