题目描述
Coffee 的世界里也是有棒棒糖卖的,Coffee 买了 nn 只连着的棒棒糖。这 nn 只棒棒糖包裹在小塑料袋中,排成 一列,相邻的两只棒棒糖的塑料袋是接起来的。为了方便,我们把棒棒糖从左到右编号为1\cdots n1⋯n。
每只棒棒糖有一种口味。第 ii 只的口味是 c_ici。两只棒棒糖 i,ji,j 的口味相同,当且仅当 c_i=c_jci=cj。Coffee 对 mm 只棒棒糖总体口味的评价比较奇怪。如果这 mm 只棒棒糖中,有一种口味 c_0c0 的数量严格大于总数的一半,那么 Coffee 认为这 mm 只棒棒糖主要是 c_0c0 口味的。Coffee 知道,这里的 c_0c0 如果存在就一定是唯一的。而当 c_0c0 不存在时,Coffee 认为这 mm 只棒棒糖是混合口味的。
Coffee 暂时舍不得吃棒棒糖,它在想一些好玩的问题。如果考虑棒棒糖序列的一个连续子序列 s\cdots t(1\leq s\leq t\leq n)s⋯t(1≤s≤t≤n),包括棒棒糖 ss 和 tt。那么这 t-s+1t−s+1 只棒棒糖的总体口味是什么呢?
Coffee有一堆这样的问题,一共 mm 个。第 ii 个问题是棒棒糖子序列 s_i\cdots t_isi⋯ti 的总体口味,请你帮忙解决。
输入格式
第一行两个用空格隔开的整数,分别表示 n,mn,m。
接下来 nn 行,每行一个整数,表示 c_ici。
接下来 mm 行,每行两个整数,表示 s_i,t_isi,ti。
输出格式
mm 行,每行一个整数,表示每个询问的总体口味。如果总体口味为混合口味则输出 00。
输入输出样例
输入 #1复制
5 3 1 2 2 1 1 1 5 2 5 2 4
输出 #1复制
1 0 2
说明/提示
样例解释 1
在第一个询问中,口味 11 出现 33 次,大于总数的一半,所以总体口味为 11。
在第二个询问中,没有一种口味出现次数大于总数的一半,所以为混合口味。
在第三个询问中,口味 22 出现 22 次,大于总数的一半,所以总体口味为 22。
数据范围
对于 100\%100% 的数据,1\leq n,m,c_i\leq 5\times 10^41≤n,m,ci≤5×104。
上代码:
#include<bits/stdc++.h>
using namespace std;
#define N 50005
int n,m,a[N],b[N],c[N],len,an[N],ans,ll=1,rr,maxn;
struct question{
int l,r,id;
}que[N];
inline int read(){
int x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x;
}//快读
inline bool cmp(question x,question y){
if(x.l/len==y.l/len)return ((x.l/len)&1)?x.r<y.r:x.r>y.r;
return x.l<y.l;
}//比较函数
multiset<int>s[N];
inline void add(int x){
s[b[a[x]]].erase(a[x]);
--c[b[a[x]]],++b[a[x]];
s[b[a[x]]].insert(a[x]);
++c[b[a[x]]];
if(b[a[x]]>maxn)++maxn;//如果超过了最大值就更新最大值
}
inline void del(int x){
s[b[a[x]]].erase(a[x]);
--c[b[a[x]]],--b[a[x]];
s[b[a[x]]].insert(a[x]);
++c[b[a[x]]];
if(b[a[x]]+1==maxn)maxn-=(c[b[a[x]]+1]==0);//如果最大值消失,就--(因为此时b[a[x]]为最大值)
}
int main(){
n=read(),m=read(),len=sqrt(n);
for(int i=1;i<=n;++i)a[i]=read();
for(int i=1;i<=m;++i)que[i].l=read(),que[i].r=read(),que[i].id=i;
sort(que+1,que+m+1,cmp);
for(int i=1;i<=n;++i)s[0].insert(a[i]),++c[0];//注意一定在开始时要加入,否则会RE
for(int i=1;i<=m;++i){
while(ll>que[i].l)add(--ll);
while(rr<que[i].r)add(++rr);
while(ll<que[i].l)del(ll++);
while(rr>que[i].r)del(rr--);//莫队正常操作
an[que[i].id]=(maxn>((que[i].r-que[i].l+1)/2))?(s[maxn].empty()?0:*s[maxn].begin()):0;//判断是否有解
}
for(int i=1;i<=m;++i)printf("%d\n",an[i]);
return 0;
}