区间合并。
当update的时候注意所查询边界是与左右儿子的边界进行比较
代码如下:
#include<cstdio>
#include<iostream>
using namespace std;
#define maxn 100005
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct node{
int r,l;
int mnum,msum;
int rnum,rsum;
int lnum,lsum;
}tree[maxn<<2];
int num[maxn],Max;
void PushUp(int rt)
{
tree[rt].mnum=(tree[rt<<1].msum>=tree[rt<<1|1].msum)?tree[rt<<1].mnum:tree[rt<<1|1].mnum;
tree[rt].msum=(tree[rt<<1].msum>=tree[rt<<1|1].msum)?tree[rt<<1].msum:tree[rt<<1|1].msum;
tree[rt].lnum=tree[rt<<1].lnum;
tree[rt].lsum=tree[rt<<1].lsum;
tree[rt].rnum=tree[rt<<1|1].rnum;
tree[rt].rsum=tree[rt<<1|1].rsum;
if(tree[rt<<1].rnum==tree[rt<<1|1].lnum)
{
int ans=tree[rt<<1].rsum+tree[rt<<1|1].lsum;
if(ans>tree[rt].msum)
{
tree[rt].msum=ans;
tree[rt].mnum=tree[rt<<1].rnum;
}
if(tree[rt<<1|1].lnum==tree[rt<<1].lnum) tree[rt].lsum+=tree[rt<<1|1].lsum;
if(tree[rt<<1].rnum==tree[rt<<1|1].rnum) tree[rt].rsum+=tree[rt<<1].rsum;
}
}
void bulid(int l,int r,int rt)
{
int m,ans;
tree[rt].l=l;
tree[rt].r=r;
if(l==r)
{
tree[rt].msum=tree[rt].lsum=tree[rt].rsum=1;
tree[rt].mnum=tree[rt].lnum=tree[rt].rnum=num[l];
return;
}
m=(l+r)>>1;
bulid(lson);
bulid(rson);
PushUp(rt);
}
void update(int x,int y,int rt)
{
int l,r;
l=tree[rt].l;
r=tree[rt].r;
int m,ans1,ans2;
if(x==l && y==r)
{
if(tree[rt].msum>Max) Max=tree[rt].msum;
return;
}
if(y<=tree[rt<<1].r) update(x,y,rt<<1);
else if(x>=tree[rt<<1|1].l) update(x,y,rt<<1|1);
else
{
m=tree[rt<<1].r;
update(x,m,rt<<1);
update(m+1,y,rt<<1|1);
if(tree[rt<<1].rnum == tree[rt<<1|1].lnum)
{
if(num[x]!=tree[rt<<1].rnum) ans1=tree[rt<<1].rsum;
else ans1=m-x+1;
if(num[y]!=tree[rt<<1|1].lnum) ans2=tree[rt<<1|1].lsum;
else ans2=y-m;
if(ans1+ans2 > Max) Max=ans1+ans2;
}
}
}
int main()
{
int i,m,a,b,n;
while(scanf("%d",&n)&& n)
{
scanf("%d",&m);
for(i=1;i<=n;i++)
scanf("%d",&num[i]);
bulid(1,n,1);
while(m--)
{
scanf("%d%d",&a,&b);
if(a==b) {printf("1\n");continue;}
Max=0;
update(a,b,1);
printf("%d\n",Max);
}
}
return 0;
}