思路:在线段树的结点内设5个变量l、r、mx、lf、rf,[l,r]表示该结点的区间范围,lf和rf分别表示元素a[l]和a[r]在区间内的出现频率,mx表示区间内的最高出现频率。
假设区间[x,y]和[y+1,z]均被询问[i,j]覆盖,则可以分情况讨论区间[x,z]的mx值:
若a[y]==a[y+1],则mx[x,y]=max{mx[x,y],mx[y+1,z],rf[x,y]+lf[y+1,z]}
否则mx[x,y]=max{mx[x,y],mx[y+1,z]}
#include
<
iostream
>
using
namespace
std;
#define
clr(x) memset(x,0,sizeof(x))
#define
max(a,b) (a>b?a:b)
#define
min(a,b) (a<b?a:b)
#define
MAXN 100002
int
a[MAXN],n,q;
struct
Node{
int
lf,rf,l,r,mx;
};
Node nod[MAXN
*
3
];
void
init(
int
tag,
int
left,
int
right){
int
temp,sum;
if
(left
==
right){
nod[tag].l
=
nod[tag].r
=
left;
nod[tag].lf
=
nod[tag].rf
=
1
;
nod[tag].mx
=
1
;
return
;
}
nod[tag].l
=
left;
nod[tag].r
=
right;
init(tag
*
2
,left,(left
+
right)
/
2
);
init(tag
*
2
+
1
,(left
+
right)
/
2
+
1
,right);
nod[tag].rf
=
nod[tag
*
2
+
1
].rf;
nod[tag].lf
=
nod[tag
*
2
].lf;
temp
=
nod[tag
*
2
].mx;
if
(nod[tag
*
2
+
1
].mx
>
temp)
temp
=
nod[tag
*
2
+
1
].mx;
if
(a[nod[tag
*
2
].r]
==
a[nod[tag
*
2
+
1
].l]){
sum
=
nod[tag
*
2
].rf
+
nod[tag
*
2
+
1
].lf;
if
(sum
>
temp)
temp
=
sum;
if
(a[nod[tag].r]
==
a[nod[tag
*
2
+
1
].l])
nod[tag].rf
=
sum;
if
(a[nod[tag].l]
==
a[nod[tag
*
2
].r])
nod[tag].lf
=
sum;
}
nod[tag].mx
=
temp;
}
int
query(
int
tag,
int
left,
int
right){
int
temp,q1,q2,sum;
if
(left
==
nod[tag].l
&&
right
==
nod[tag].r){
return
nod[tag].mx;
}
if
(right
<=
nod[
2
*
tag].r)
return
query(tag
*
2
,left,right);
else
if
(left
>=
nod[
2
*
tag
+
1
].l)
return
query(tag
*
2
+
1
,left,right);
else
{
q1
=
query(tag
*
2
,left,nod[tag
*
2
].r);
q2
=
query(tag
*
2
+
1
,nod[tag
*
2
+
1
].l,right);
temp
=
q1;
if
(q2
>
temp)
temp
=
q2;
if
(a[nod[tag
*
2
].r]
==
a[nod[tag
*
2
+
1
].l]){
sum
=
min(nod[tag
*
2
].r
-
left
+
1
,nod[tag
*
2
].rf)
+
min(right
-
nod[tag
*
2
+
1
].l
+
1
,nod[tag
*
2
+
1
].lf);
if
(sum
>
temp)
temp
=
sum;
}
return
temp;
}
}
int
main(){
int
i,x,y;
while
(scanf(
"
%d
"
,
&
n)
&&
n){
scanf(
"
%d
"
,
&
q);
for
(i
=
1
;i
<=
n;i
++
)
scanf(
"
%d
"
,
&
a[i]);
init(
1
,
1
,n);
for
(i
=
0
;i
<
q;i
++
){
scanf(
"
%d%d
"
,
&
x,
&
y);
printf(
"
%d\n
"
,query(
1
,x,y));
}
}
return
0
;
}