一道练习莫队的好题
用vis维护范围内每个数的出现次数
用cntvis维护出现某次数的数字的种类数
//cyc
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
#include<bits/stdc++.h>
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,a,n) for(int i=n;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define mst(a) memset(a,0,sizeof a)
using namespace std;
typedef pair<int,int> pii;
const int maxn=3e5+5;
int ansp=0;
struct st
{
int l,r,blc,id;
}stc[maxn];
int a[maxn];
int vis[maxn];
int n,q;
int bloc;
bool cmp(st s1,st s2)
{
if(s1.blc!=s2.blc)return s1.blc<s2.blc;
else{
return s1.r<s2.r;
}
}
int ans[maxn];
int cntvis[maxn];
void add(int x)
{
vis[a[x]]++;
cntvis[vis[a[x]]]++;
if(cntvis[vis[a[x]]]==1)ansp++;
}
void del(int x)
{
cntvis[vis[a[x]]]--;
if(!cntvis[vis[a[x]]])ansp--;
vis[a[x]]--;
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>q;
bloc=sqrt(n);
int l,r;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=q;i++){
cin>>l>>r;
stc[i]={l,r,(l-1)/bloc+1,i};
}
sort(stc+1,stc+1+q,cmp);
l=stc[1].l;
r=l-1;
for(int i=1;i<=q;i++){
while(l>stc[i].l){
l--;
add(l);
}
while(r<stc[i].r){
r++;
add(r);
}
while(l<stc[i].l){
del(l);
l++;
}
while(r>stc[i].r){
del(r);
r--;
}
int len;
len=1+stc[i].r-stc[i].l;
if(ansp<=(len+1)/2){
ans[stc[i].id]=1;
}
else{
ans[stc[i].id]=ansp-(len-ansp+1)+1;
}
}
for(int i=1;i<=q;i++)cout<<ans[i]<<endl;
}