Link
Solve
通过观察我们发现,对于一列数,rp减小值就是众数的个数,由于可以离线,我们就可以用莫队来解决这个问题,每次几下cntx,retx有点难理解,加入一个数的时候,用Ans刷cnt的max,删除一个数时,判断这个数是不是众数,如果只有有且只有一个删除的cnt而且删除的是当前的众数是,我们把Ans--,因为如果ret[cnt[x]-1]肯定不为0,可能是当前是这个数,也可能有好多个众数,剩下的就是莫队了。
Code
#include<bits/stdc++.h>
using namespace std;
const int maxn=200005;
int n,m,cnt[maxn],a[maxn],block[maxn],ans[maxn],len,tot,now,ret[maxn];
struct AS{
int x,id;
bool operator <(const AS B)const {return x<B.x;}
}c[maxn];
struct BS{
int l,r,id;
bool operator <(const BS B)const {return block[l]^block[B.l]?block[l]<block[B.l]:(block[l]&1)?r<B.r:r>B.r;}
}q[maxn];
inline int read(){
int ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
void inc(int x){
ret[cnt[x]]--;
ret[++cnt[x]]++;
now=max(now,cnt[x]);
}
void del(int x){
ret[cnt[x]]--;
if(ret[cnt[x]]==0&&cnt[x]==now)now--;
cnt[x]--;
ret[cnt[x]]++;
}
int main(){
freopen("P3709.in","r",stdin);
freopen("P3709.out","w",stdout);
n=read();m=read();len=sqrt(n);
for(int i=1;i<=n;i++)c[i].x=read(),c[i].id=i,block[i]=(i-1)/len+1;
sort(c+1,c+1+n);
a[c[1].id]=++tot;
for(int i=2;i<=n;i++){
if(c[i].x!=c[i-1].x)tot++;
a[c[i].id]=tot;
}
for(int i=1;i<=m;i++)q[i].l=read(),q[i].r=read(),q[i].id=i;
sort(q+1,q+1+m);
int L=1,R=0;
for(int i=1;i<=m;i++){
while(L<q[i].l)del(a[L++]);
while(L>q[i].l)inc(a[--L]);
while(R<q[i].r)inc(a[++R]);
while(R>q[i].r)del(a[R--]);
ans[q[i].id]=now;
}
for(int i=1;i<=m;i++)printf("%d
",-ans[i]);
return 0;
}