经典莫队
解释一下 2x-len
x为超限的个数, len-x为好的个数
好块能容纳的个数为 len-x+1
剩下不能容纳的超限数的个数为x-(len-x+1)
单独划走一个是最优秀的
再加上 好的那块 就是2*x-len
#include<bits/stdc++.h> #define ll long long using namespace std; const int mod = 1e9+7; const int maxn = 2e6+10; int n,m; int ans[maxn],res,cnt[maxn],sum[maxn],a[maxn]; struct node{ int l,r,qid,blo; int len(){ return r-l+1; } bool operator<(const node&rhs)const{ if(blo^rhs.blo) return l<rhs.l; return blo & 1 ? r<rhs.r : rhs.r<r; } }q[maxn]; void add(int x){ sum[cnt[a[x]]]--; cnt[a[x]]++; res=max(res,cnt[a[x]]); sum[cnt[a[x]]]++;//个数的个数++ } void del(int x){ sum[cnt[a[x]]]--; if(sum[cnt[a[x]]]==0&&cnt[a[x]]==res) res--; cnt[a[x]]--; sum[cnt[a[x]]]++; } int main(){ ios::sync_with_stdio(false); cin>>n>>m; for(int i=1;i<=n;++i){ cin>>a[i]; } int block=(int)(sqrt(n>=3?n*(2.0/3):n)); for(int i=1;i<=m;++i){ cin>>q[i].l>>q[i].r; q[i].qid=i; q[i].blo=q[i].l/block; } sort(q+1,q+1+m); int l=0,r=0; for(int i =1;i<=m;++i){ while(l < q[i].l)del(l++); while(l > q[i].l)add(--l); while(r < q[i].r)add(++r); while(r > q[i].r)del(r--); ans[q[i].qid ] = max(1,res*2-q[i].len()); } for(int i=1;i<=m;++i) printf("%d ",ans[i]); return 0; }