莫队维护区间众数出现次数
这个莫队是求的众数出现的次数,不能求出那个众数是那个数
题意:
给定数组a长度为n,q次询问,
每次询问给定L,R,你可以将[L,R]中的数放进若干个盒子,
要求满足每盒子中的众数出现次数<=(盒子中数总数+1)/2,
问最少需要多少个盒子。
数据范围:n,q<=3e5,a(i)<=n
设[l,r]的长度为len,众数个数为cnt,那么非众数个数x=len-cnt. x个非众数可以和x+1个众数放在一起,满足条件, 多出来的众数只能一个一个放了,个数为cnt-(x+1). 因此需要的总个数为cnt-(len-cnt+1)+1=cnt*2-len.
void add(int pos){ sum[z[a[pos]]]--;//3变4了 z[a[pos]]++; sum[z[a[pos]]]++; ans=max(ans,z[a[pos]]); } void remove(int pos){ sum[z[a[pos]]]--; if(z[a[pos]]==ans&&sum[z[a[pos]]]==0) ans--; z[a[pos]]--; sum[z[a[pos]]]++; }
重点就是怎么维护这个众数出现的次数,就是你先有一个数组z[i]来维护a[i]出现的次数,
然后再用一个数组sum[i]代表的是z[i]出现次数,例如:
sum[z[5]]--;
z[5]++;
sum[z[5]]++;这是加的操作
加入次数5为出现最多的数出现了4次,马上要减少1次
sum[5]--;
当出现5次的为0的时候那么就是就是没有出现5次的数了,然后ans--
为什么这样呢?
就是一个区间内出现次数最多的数可能出现多次,所以你不能直接ans--
#include<iostream> #include<algorithm> #include<math.h> using namespace std; typedef long long ll; const int maxn=5e6+100; inline ll read() { ll x = 0; bool f = 0; char ch = getchar(); while (ch < '0' || '9' < ch) f |= ch == '-', ch = getchar(); while ('0' <= ch && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return f ? -x : x; } int belong[maxn],res[maxn]; int a[maxn]; int z[maxn]; int sum[maxn]; int block; struct node{ int l,r,id; }q[maxn]; bool cmp(node x,node y){ if(belong[x.l]!=belong[y.l]){ return x.l<y.l; } else{ if(belong[x.l]&1){ return x.r<y.r; } else{ return x.r>y.r; } } } int ans=0; void add(int pos){ sum[z[a[pos]]]--;//3变4了 z[a[pos]]++; sum[z[a[pos]]]++; ans=max(ans,z[a[pos]]); } void remove(int pos){ sum[z[a[pos]]]--; if(z[a[pos]]==ans&&sum[z[a[pos]]]==0) ans--; z[a[pos]]--; sum[z[a[pos]]]++; } int main(){ int n,m; n=read(); m=read(); block=sqrt(n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); belong[i]=(i-1)/block+1; } 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); int l=1,r=0; int len; for(int i=1;i<=m;i++){ int ql=q[i].l,qr=q[i].r; while(l<ql){ remove(l++); } while(l>ql){ add(--l); } while(r>qr){ remove(r--); } while(r<qr){ add(++r); } len=(qr-ql+1); res[q[i].id]=max(1,2*ans-len); } for(int i=1;i<=m;i++){ printf("%d\n",res[i]); } }
主席树不会: