莫队算法板子
FZSZ Online Judge #36 C. 【Noip模拟 20161015】众数查询
题目描述
给你n个数a1,a2,...,an以及q个询问[L,R],对于每个询问,回答[L,R]中的数的众数的出现次数是多少。
输入格式
第一行一个整数n。
第二行n个整数,a1,a2,...,an。
第三行一个整数q。
接下来q行,每行两个整数L,R,表示一组询问。
输出格式
对于每个询问,每行表示相应询问的答案。
样例输入
5
1 1 2 2 3
3
1 2
2 5
1 5
样例输出
2
2
2
数据范围
对于20%的数据,n≤100,q≤100.
对于40%的数据,n≤100,q≤104.
对于80%的数据,n≤1000,q≤2×104.
对于100%的数据,1≤n,q≤8×104,0≤ai≤106.
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<algorithm> #define BIG 80011 #define MAX 1000011 #define FOR(i,s,t) for(register int i=s;i<=t;++i) using namespace std; struct ques{ int l; int r; int bs; }Q[BIG]; int a[BIG],f[MAX],have[BIG],ans[BIG]; int n,m,p,q,l,r; inline int read(){ char c=getchar(); int data=0,w=1; while((c>'9'||c<'0')&&c!='-') c=getchar(); if(c=='-') w=-1,c=getchar(); while(c>='0'&&c<='9') data=(data<<1)+(data<<3)+c-48,c=getchar(); return data*w; } int wr[51]; inline void write(int x){ if(x<0) x=-x,putchar('-'); if(x==0){ putchar(48); putchar('\n'); return ; } while(x) wr[++wr[0]]=x%10,x/=10; while(wr[0]) putchar(48+wr[wr[0]--]); putchar('\n'); } inline bool cmp(ques a,ques b){ return a.l/m<b.l/m||a.l/m==b.l/m&&a.r<b.r; } inline void add(int x){ ++have[x]; ++f[have[x]]; --f[have[x]-1]; if(have[x]>p) p=have[x]; } inline void cancel(int x){ --have[x]; --f[have[x]+1]; ++f[have[x]]; if(!f[p]&&p==have[x]+1) p=have[x]; } int main(){ n=read(); FOR(i,1,n) a[i]=read(); q=read(); FOR(i,1,q) Q[i].l=read(),Q[i].r=read(),Q[i].bs=i; m=sqrt(n); sort(Q+1,Q+q+1,cmp); l=1; r=0; FOR(i,1,q){ while(Q[i].r>r) add(a[++r]); while(Q[i].r<r) cancel(a[r--]); while(Q[i].l<l) add(a[--l]); while(Q[i].l>l) cancel(a[l++]); ans[Q[i].bs]=p; } FOR(i,1,q) write(ans[i]); return 0; }