###题目:
###AC代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#define maxn 100000 + 10
using namespace std;
typedef long long LL;
LL a[maxn];
LL st[maxn],ed[maxn];
LL n;
LL N,M,K,T;
LL d[maxn][18];
void predig()
{
memset(d,0,sizeof(d));
for (int i = 0; i<n; i++)
{
d[i][0] = st[i+1];
}
for (LL j = 1; (1 << j) <= n; j++)
{
for (LL i = 0; (i + (1 << j) - 1)<n; i++)
{
d[i][j] = max(d[i][j - 1], d[i + (1 << (j - 1))][j - 1]);
}
}
}
LL rmq(LL l, LL r)
{
LL k = 0;
while (1 << (k + 1) <= (r - l + 1)) k++;
return max(d[l][k], d[r - (1 << k) + 1][k]);
}
void solve()
{
a[0] = a[1] * (-1);
for(int i = 1; i <= n; i++)
{
if(a[i] == a[i-1]) st[i] = st[i-1] + 1;
else st[i] = 1;
}
a[n+1] = a[n] *(-1);
for(int i = n; i > 0; i--)
{
if(a[i] == a[i+1]) ed[i] = ed[i+1];
else ed[i] = i;
}
predig();
while(T--)
{
LL L,R;
scanf("%lld%lld",&L,&R);
if(ed[L] >= R)
printf("%lld\n",R - L + 1);
else printf("%lld\n",max(ed[L]-L + 1,rmq(ed[L],R-1)));
}
}
int main()
{
while(cin>>n&&n)
{
scanf("%lld",&T);
for(int i = 1; i <= n; i++)
scanf ("%lld",&a[i]);
solve();
}
return 0;
}
###题解:
1.正序扫描:st[maxn]标记各自出现次数:-1 (1)-1(2) 1(1) 1(2) 1 (3)1 (4)3(1) 10(1) 10 (2)10(3)
2.倒序扫描:ed[maxn]标记各自值最后出现的位置:-1 (2)-1(2) 1(6) 1(6) 1 (6)1 (6)3(7) 10(10) 10 (10)10(10)
3.当ed[L] >= R ans = R - L + 1;
当ed[L] < R ans = max(ed[L]-L + 1,rmq(ed[L],R-1))