链接
https://vjudge.net/problem/UVA-11235
题解
维护从这个数到左边一直数能数几个和它相等的数,往右维护相同的东西
记为
l
i
,
r
i
l_i,r_i
li,ri
那么每一段我就把它最右边的那段切出来之后,剩下的
r
i
r_i
ri的最大值和最右边一段的长度取
m
a
x
max
max就是答案
代码
#include <bits/stdc++.h>
#define maxn 100010
#define maxk 20
using namespace std;
typedef long long ll;
ll read(ll x=0)
{
ll c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return f*x;
}
class ST
{
private:
ll st[maxn][maxk], n;
public:
void create(ll *a, ll N)
{
ll i, j, k;
n=N;
for(i=1;i<=N;i++)st[i][0]=a[i];
for(k=1;(1ll<<k)<=N;k++)
{
for(i=1;i+(1<<k-1)<=N;i++)
{
st[i][k]=max(st[i][k-1],st[i+(1<<k-1)][k-1]);
}
}
}
ll qmax(ll l, ll r)
{
ll k=floor(log2(r-l+1));
return max(st[l][k],st[r-(1<<k)+1][k]);
}
}st;
ll N, a[maxn], q, l[maxn], r[maxn];
int main()
{
ll i, ans, x, y;
while(scanf("%lld%lld",&N,&q), N)
{
for(i=1;i<=N;i++)a[i]=read();
l[1]=1;
for(i=2;i<=N;i++)
{
if(a[i]==a[i-1])l[i]=l[i-1]+1;
else l[i]=1;
}
r[N]=1;
for(i=N-1;i;i--)
{
if(a[i]==a[i+1])r[i]=r[i+1]+1;
else r[i]=1;
}
st.create(r,N);
while(q--)
{
x=read(), y=read();
ans=min(y-x+1,l[y]);
if(y-l[y]>=x)ans=max(ans,st.qmax(x,y-l[y]));
printf("%lld\n",ans);
}
}
return 0;
}