每个节点额外存5个信息,lx为最左边的端点的序号,lf为跟最左边那个端点序号相等的点的个数,max为这段线段中相等节点个数最大值;rx为最左边的端点的序号,rf为跟最左边那个端点序号相等的点的个数。
#include <stdio.h>
#define N 100010
#define MAX(x,y) (x>y?x:y)
int a[N];
struct node
{
int left,right,mid;
int lx,rx,max,lf,rf;
}bt[4*N];
void make(int l,int r,int num)
{
int temp;
if (l>r) return ;
bt[num].left=l;
bt[num].right=r;
bt[num].mid=(l+r)/2;
if(l!=r)
{
make(l,bt[num].mid,2*num);
make(bt[num].mid+1,r,2*num+1);
bt[num].lx=bt[2*num].lx;bt[num].rx=bt[2*num+1].rx;
bt[num].lf=bt[2*num].lf;
bt[num].rf=bt[2*num+1].rf;
if ((bt[2*num].lx==bt[2*num].rx)&&(bt[2*num].rx==bt[2*num+1].lx)) bt[num].lf=bt[2*num].lf+bt[2*num+1].lf;
if ((bt[2*num+1].lx==bt[2*num+1].rx)&&(bt[2*num].rx==bt[2*num+1].lx)) bt[num].rf=bt[2*num].rf+bt[2*num+1].rf;
temp=0;
if (bt[2*num].rx==bt[2*num+1].lx) temp=bt[2*num].rf+bt[2*num+1].lf;
bt[num].max=MAX(bt[2*num].max,bt[2*num+1].max);
bt[num].max=MAX(bt[num].max,temp);
}
else
{
bt[num].lx=bt[num].rx=a[l];
bt[num].lf=bt[num].rf=1;
bt[num].max=1;
}
}
int cal(int l,int r,int num)
{
int rt, lt;int ll,rr,temp;
if(bt[num].left==l&&bt[num].right==r)
return bt[num].max;
else if(r<=bt[num].mid)
return cal(l,r,2*num);
else if(l>bt[num].mid)
return cal(l,r,2*num+1);
else
{
ll=cal(l,bt[num].mid,2*num);
rr=cal(bt[num].mid+1,r,2*num+1);
temp=ll>rr?ll:rr;
if(bt[2*num].rx==bt[2*num+1].lx)
{
if(bt[2*num].rf>bt[num].mid-l+1) rt=bt[num].mid-l+1;
else rt=bt[2*num].rf;
if(bt[2*num+1].lf>r-bt[num].mid) lt=r-bt[num].mid;
else lt=bt[2*num+1].lf;
if(temp<rt+lt) temp=rt+lt;
}
return temp;
}
}
int main()
{
int i,n,m,s,t;
while(scanf("%d",&n)!=EOF)
{
if (n==0) break;
scanf("%d",&m);
for(i=1;i<=n;++i) scanf("%d",&a[i]);
make(1,n,1);
for(i=1;i<=m;++i)
{
scanf("%d%d",&s,&t);
printf("%d/n",cal(s,t,1));
}
}
return 0;
}