[ZJb417]区间众数
题目大意:
给定一个长度为$n(1\leq n\leq10^5)$的正整数序列$s(1\leq s_i\leq n)$,对于$m(1\leq m\leq10^)$次询问$l,r$,每次求区间$[s_l,\ldots,s_r]$中,众数出现的次数以及众数的个数。
思路:
莫队。
对于询问$l,r$,维护每个数$s_i$出现的次数$cnt1[i]$以及每个$cnt1[i]$出现的次数$cnt2[i]$。
1 #include<cmath> 2 #include<cstdio> 3 #include<cctype> 4 #include<algorithm> 5 inline int getint() { 6 register char ch; 7 while(!isdigit(ch=getchar())); 8 register int x=ch^'0'; 9 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 10 return x; 11 } 12 const int N=100001,M=1000000; 13 int a[N],belong[M],cnt1[N],cnt2[N],tmp,ans1[M],ans2[M]; 14 struct Query { 15 int l,r,id; 16 bool operator < (const Query &another) const { 17 if(belong[l]==belong[another.l]) return belong[r]<belong[another.r]; 18 return belong[l]<belong[another.l]; 19 } 20 }; 21 Query q[M]; 22 inline void ins(const int &x) { 23 cnt2[cnt1[a[x]]++]--; 24 cnt2[cnt1[a[x]]]++; 25 tmp=std::max(tmp,cnt1[a[x]]); 26 } 27 inline void del(const int &x) { 28 cnt2[cnt1[a[x]]--]--; 29 cnt2[cnt1[a[x]]]++; 30 while(!cnt2[tmp]) tmp--; 31 } 32 int main() { 33 const int n=getint(),m=getint(),block=sqrt(n); 34 for(register int i=1;i<=n;i++) { 35 a[i]=getint(); 36 belong[i]=i/block; 37 } 38 for(register int i=0;i<m;i++) { 39 const int l=getint(),r=getint(); 40 q[i]=(Query){l,r,i}; 41 } 42 std::sort(&q[0],&q[m]); 43 for(register int i=0,l=1,r=0;i<m;i++) { 44 while(l<q[i].l) del(l++); 45 while(l>q[i].l) ins(--l); 46 while(r<q[i].r) ins(++r); 47 while(r>q[i].r) del(r--); 48 ans1[q[i].id]=tmp; 49 ans2[q[i].id]=cnt2[tmp]; 50 } 51 for(register int i=0;i<m;i++) { 52 printf("%d %d\n",ans1[i],ans2[i]); 53 } 54 return 0; 55 }