给一个长度为n的序列a。1≤a[i]≤n。
m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2。如果存在,输出这个数,否则输出0。
给一个长度为n的序列a。1≤a[i]≤n。
m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2。如果存在,输出这个数,否则输出0。
第一行两个数n,m。
第二行n个数,a[i]。
接下来m行,每行两个数l,r,表示询问[l,r]这个区间。
m行,每行对应一个答案。
【数据范围】
n,m≤500000
解题思路:主席树模板
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using
namespace
std;
int
n,m,sz;
int
sum[10000010];
int
root[500010];
int
l[10000010];
int
r[10000010];
inline
int
read()
{
char
y;
int
x=0,f=1; y=
getchar
();
while
(y<
'0'
|| y>
'9'
) {
if
(y==
'-'
) f=-1; y=
getchar
();}
while
(y>=
'0'
&& y<=
'9'
) {x=x*10+
int
(y)-48;y=
getchar
();}
return
x*f;
}
void
updata(
int
lg,
int
rg,
int
x,
int
&y,
int
v)
{
y=++sz; sum[y]=sum[x]+1;
if
(lg==rg)
return
;
l[y]=l[x]; r[y]=r[x];
int
mid=(lg+rg)/2;
if
(v<=mid) updata(lg,mid,l[x],l[y],v);
else
updata(mid+1,rg,r[x],r[y],v);
}
int
query(
int
lg,
int
rg)
{
int
tmp=(rg-lg+1)/2;
int
ll=1;
int
rr=n;
lg=root[lg-1]; rg=root[rg];
while
(ll!=rr)
{
if
(sum[rg]-sum[lg]<=tmp)
return
0;
int
mid=(ll+rr)/2;
if
(sum[l[rg]]-sum[l[lg]]>tmp)
{
lg=l[lg]; rg=l[rg]; rr=mid;
}
else
if
(sum[r[rg]]-sum[r[lg]]>tmp)
{
ll=mid+1; lg=r[lg]; rg=r[rg];
}
else
return
0;
}
return
ll;
}
int
main()
{
n=read(); m=read(); sz=0;
for
(
int
i=1;i<=n;++i)
{
int
x=read();
updata(1,n,root[i-1],root[i],x);
}
for
(
int
i=1;i<=m;++i)
{
int
x,y; x=read(); y=read();
printf
(
"%d\n"
,query(x,y));
}
}