莫队算法板子

题目描述

给你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%的数据,n100,q100.

对于40%的数据,n100,q104.

对于80%的数据,n1000,q2×104.

对于100%的数据,1n,q8×104,0ai106.

#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;
}

  

转载于:https://www.cnblogs.com/Stump/p/7687433.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值