脑子实在太死板了, 竟然就想着用纯的线段树来解决, 一直对那种不完全的区间不能分开, 看了下别人的解法, 都是离散了然后把2边可能不完全的区间去掉再进行的线段树的操作的。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define L(u) (u<<1)
#define R(u) (u<<1|1)
using namespace std;
const int Maxn = 100010;
struct Node {
int l, r, ma;
} node[Maxn<<2];
struct Dis{
int s, e;
} dis[Maxn];
int num, n, m, flag[Maxn];
int max(int a,int b)
{
return a>b?a:b;
}
void pushUp(int u)
{
node[u].ma = max(node[L(u)].ma, node[R(u)].ma);
}
void build(int u,int left,int right)
{
node[u].l = left,node[u].r = right;
node[u].ma = 0;
if(node[u].l==node[u].r)
{
node[u].ma = dis[left].e - dis[left].s + 1;
return;
}
int mid = (node[u].l+node[u].r)>>1;
build(L(u),left,mid);
build(R(u),mid+1,right);
pushUp(u);
}
int query(int u,int left,int right)
{
if(left<=node[u].l&&node[u].r<=right)
return node[u].ma;
if(right < left)
return 0;
int mid = (node[u].l+node[u].r)>>1;
if(right<=mid)
return query(L(u),left,right);
else if(left>mid)
{
return query(R(u),left,right);
}
else
{
return max(query(L(u),left,mid),query(R(u),mid+1,right));
}
}
int main(void)
{
while(scanf("%d",&n), n)
{
scanf("%d",&m);
num = 0;
int tmp, pre = 100000000, s = 0, e = 0;
for(int i=1; i<=n; ++i)
{
scanf("%d",&tmp);
if(pre != tmp)
{
dis[num].s = s;
dis[num].e = e;
num++;
pre = tmp;
s = i;
}
e = i;
flag[i] = num;
}
dis[num].s = s;
dis[num].e = e;
build(1,1,num);
int a, b;
while(m--)
{
scanf("%d %d",&a,&b);
int t1 = flag[a];
int t2 = flag[b];
if(t1 == t2)
{
printf("%d\n",b-a+1);
}
else
{
int tmp = max(dis[t1].e - a +1 , b-dis[t2].s+1);
tmp = max(tmp, query(1, t1+1, t2-1));
printf("%d\n",tmp);
}
}
}
return 0;
}