洛谷 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\times 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\n",ans[i]);
}
return 0;
}