首先这个题面弯弯绕绕就读不懂
瞟了一眼题解,就是求一个区间里面的众数的出现次数。
因为这个区间不更改,可离线,那就上莫队就行了
莫队求众数,记 x 出现次数 cnt[x],记出现次数为 n 的数的个数为 num[n],当前众数的次数为 now
添加的话,直接修改 cnt 和 num,用 cnt 去更新 now
删除的话,如果这时 num[cnt[x]] == 1 并且 cnt[x] == now,那么删除 x 之后,就没有 cnt == now 的数了,now--。也可以像代码里那样处理
#include <iostream> #include <stdlib.h> #include <stdio.h> #include <math.h> #include <string.h> #include <algorithm> #define MAXN 200010 using namespace std; int n,m,a[MAXN],b[MAXN],pos[MAXN],ans[MAXN],cnt[MAXN],num[MAXN],now; struct Ques{ int l,r,id; }q[MAXN]; bool cmp(Ques x,Ques y){return pos[x.l]<pos[y.l]||pos[x.l]==pos[y.l]&&x.r<y.r;} void add(int x){ num[cnt[x]]--; num[++cnt[x]]++; now=max(now,cnt[x]); } void del(int x){ num[cnt[x]]--; if(cnt[x]==now&&!num[cnt[x]]) now--; num[--cnt[x]]++; } int main(){ scanf("%d%d",&n,&m); int sz=sqrt(n); for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i],pos[i]=i/sz; sort(b+1,b+n+1); int tot=unique(b+1,b+n+1)-b-1; for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+tot+1,a[i])-b; for(int i=1;i<=m;i++) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i; sort(q+1,q+m+1,cmp); int L=0,R=0; num[0]=tot; for(int i=1;i<=m;i++){ while(R<q[i].r) add(a[++R]); while(R>q[i].r) del(a[R--]); while(L>q[i].l) add(a[--L]); while(L<q[i].l) del(a[L++]); ans[q[i].id]=-now; } for(int i=1;i<=m;i++) printf("%d ",ans[i]); return 0; }