语文题啊……
看题解发现是让求区间中最多的数的个数,于是果断理解了一会题解……莫队套上完事。
sum[i]表示i这个数出现的次数,cnt[i]表示出现i次的数有几个,然后乱搞搞……就好了
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<cctype> #include<cmath> #define maxn 300000 using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch==‘-‘) f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-‘0‘; ch=getchar(); } return num*f; } int s[maxn]; int q[maxn]; int d[maxn]; int ans[maxn]; struct Que{ int x,y,id; bool operator <(const Que a)const{ if(s[x]!=s[a.x]) return s[x]<s[a.x]; return y<a.y; } }que[maxn]; int sum[maxn],cnt[maxn]; int main(){ int n=read(),m=read(); int sqt=sqrt(n); for(int i=1;i<=n;++i){ q[i]=d[i]=read(); s[i]=(i-1)/sqt+1; } sort(q+1,q+n+1); int size=unique(q+1,q+n+1)-q-1; for(int i=1;i<=n;++i) d[i]=lower_bound(q+1,q+size+1,d[i])-q; for(int i=1;i<=m;++i) que[i]=(Que){read(),read(),i}; sort(que+1,que+m+1); int l=0,r=0,now=1;cnt[0]=1; for(int i=1;i<=m;++i){ int x=que[i].x,y=que[i].y; while(r<y){ r++; int &o=sum[d[r]]; if(now==o) now++; cnt[o]--; o++; cnt[o]++; } while(r>y){ int &o=sum[d[r]]; cnt[o]--; if(now==o&&cnt[o]==0) now--; o--; cnt[o]++; r--; } while(l<x){ int &o=sum[d[l]]; cnt[o]--; if(now==o&&cnt[o]==0) now--; o--; cnt[o]++; l++; } while(l>x){ l--; int &o=sum[d[l]]; cnt[o]--; if(now==o) now++; o++; cnt[o]++; } ans[que[i].id]=now; } for(int i=1;i<=n;++i) printf("%d\n",-ans[i]); return 0; }
原文地址:https://www.cnblogs.com/cellular-automaton/p/8318846.html
时间: 2024-10-27 17:23:47