洛谷 P1997 faebdc 的烦恼

题目背景
鸟哥(faebdc)自从虐暴 NOIP2013 以来依然勤奋学习,每天上各种 OJ 刷题,各种比赛更是不在话下。但这天他遇到了一点小小的麻烦:在一届“Orz 鸟哥杯”上,题目是在是太多了!鸟哥看得头晕眼花,他需要你的帮助。

题目描述
这场比赛共有 nn 道题,每道题都有一个难度值 a_ia
i

,由于 wangxz 神犇已经提前帮助鸟哥将这些难度值升序排列,所以鸟哥并不想知道哪些题难度低或者高,他只想知道在某些题目 a_l,a_{l+1},ldots,a_ra
l

,a
l+1

,…,a
r

中,出现最多的难度值出现的次数。

你的任务就是对于鸟哥的每一次询问 (l, r)(l,r),告诉他在从 a_la
l

到 a_ra
r

这 (r-l+1)(r−l+1) 道题之中,出现最多的难度值出现的次数(询问共有 qq 次)。

如果你成功地帮助了鸟哥,鸟哥将会带你通过省选。

输入格式
每个测试点有且仅有一组测试数据。

第一行有两个整数,分别表示题目的数量 nn 和询问的次数 qq。

第二行有 nn 个整数,第 ii 个整数 a_ia
i

表示第 ii 道题的难度。

接下来 qq 行,每行两个整数 l, rl,r,表示一次询问。

输出格式
对于每组询问,输出一行一个整数表示答案。

输入输出样例
输入 #1 复制
9 1
1 1 1 2 2 3 3 4 4
3 8
输出 #1 复制
2
说明/提示
数据规模与约定
对于全部的测试点,保证 1 leq n leq 10^51≤n≤10
5
,1 leq q leq 2 imes 10^51≤q≤2×10
5
,-10^5 leq a_i leq 10^5−10
5
≤a
i

≤10
5
,1 leq l leq r leq n1≤l≤r≤n。

思路:区间众数模板题,由于没有修改操作,不妨用莫队来解决。设c[i]为数字i在当前区间出现的次数,p[i]为当前区间出现次数为i的数字的个数,然后自己模拟一下就行了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;//simplify long long
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
#define inf 2147483647
#define pi 3.14159265358979
#define rep(i, l, r) for(int i = l; i <= r; i ++)
#define lop(i, r, l) for(int i = r; i >= l; i --)
#define step(i, l, r, __step) for(int i = l; i <= r; i += __step)
#define revp(i, r, l, __step) for(int i = r; i >= l; i -= __step)
#define reg regsiter
#define RI regsiter int
#define RL regsiter long long
#define rerep(i, l, r) for(regsiter int i = l; i <= r; i ++)
#define relop(i, r, l) for(regsiter int i = r; i >= l; i --)
#define i8 __int128
#define __int128 ll//don't forget delete it in contest!
inline int read()//fast read
{
	int ret = 0, sgn = 1;
	char chr = getchar();
	while(chr < '0' || chr > '9')
	{if(chr == '-') sgn = -1; chr = getchar();}
	while(chr >= '0' && chr <= '9')
	{ret = ret * 10 + chr - '0'; chr = getchar();}
	return ret * sgn;
}
i8 write(i8 x)//int128's output
{
	if(x < 0) putchar('-'), x = -x;
	if(x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
const int N = 2e5 + 10;
const int M = 2e5 + 10;
int c[N],p[N],ans[N],inbl[N];
struct query{
	int l,r,id;
}q[M];
inline bool cmp(query A,query B)
{
	if(inbl[A.l]^inbl[B.l]) return inbl[A.l]<inbl[B.l];
	if(inbl[A.l]&1) return A.r<B.r;
	return A.r>B.r;
}
int now,num[N],kl,kcnt;
inline void add(int x)
{
	p[c[num[x]]]--;
	c[num[x]]++;
	p[c[num[x]]]++;
	if(now<c[num[x]]) now=c[num[x]];
}
inline void del(int x)
{
	p[c[num[x]]]--;
	c[num[x]]--;
	p[c[num[x]]]++;
	if(c[num[x]]==now-1&&!p[c[num[x]]+1]) now--; 
}
int main()
{
	int n,m;
	n=read(),m=read();
	kl=sqrt(n);
	kcnt=ceil((double)n/kl);
	rep(i,1,kcnt)
		rep(j,(i-1)*kl+1,i*kl)
			inbl[j]=i;
	rep(i,1,n) num[i]=read(),num[i]+=1e5;
	rep(i,1,m)
	{
		q[i].l=read(),q[i].r=read();
		q[i].id=i;
	}
	sort(q+1,q+1+m,cmp);
	int l=1,r=0;
	rep(i,1,m)
	{
		int ql=q[i].l,qr=q[i].r;
		while(l<ql) del(l++);
		while(l>ql) add(--l);
		while(r<qr) add(++r);
		while(r>qr) del(r--);
		ans[q[i].id]=now;
	}
	rep(i,1,m)
	{
		printf("%d
",ans[i]);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/loi-frank/p/14002772.html