题目大意:区间相同颜色连续的最大长度
题目解析:线段树节点保存左右端点颜色,从左右开始的最大长度和答案,pushup和query的时候考虑左儿子右端点和右儿左端点的颜色是否一样需要特判;
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
const int maxn = 1e5+10;
struct node
{
int l,r;
int ma;
int lc,rc;
int ls,rs;
}tree[maxn<<2];
void pushup(int rt)
{
tree[rt].ls=tree[lson].ls;
tree[rt].rs=tree[rson].rs;
tree[rt].l=tree[lson].l;
tree[rt].r=tree[rson].r;
tree[rt].lc=tree[lson].lc;
tree[rt].rc=tree[rson].rc;
tree[rt].ma=max(tree[lson].ma,tree[rson].ma);
if(tree[lson].rc==tree[rson].lc)
{
if(tree[lson].ls==tree[lson].r-tree[lson].l+1)
tree[rt].ls=tree[lson].ls+tree[rson].ls;
if(tree[rson].rs==tree[rson].r-tree[rson].l+1)
tree[rt].rs=tree[rson].rs+tree[lson].rs;
int sum = tree[lson].rs+tree[rson].ls;
tree[rt].ma=max(tree[rt].ma,sum);
}
}
void build(int l,int r,int rt)
{
if(l==r)
{
int c;
scanf("%d",&c);
tree[rt].lc=tree[rt].rc=c;
tree[rt].ls=tree[rt].rs=1;
tree[rt].l=l;
tree[rt].r=r;
tree[rt].ma=1;
return ;
}
int mid =(l+r)>>1;
build(l,mid,lson);
build(mid+1,r,rson);
pushup(rt);
}
int query(int l,int r,int rt)
{
//cout<<l<<" "<<r<<endl;
if(l==tree[rt].l&&r==tree[rt].r){
return tree[rt].ma;
}
int mid = (tree[rt].l+tree[rt].r)>>1;
if(l>mid)
return query(l,r,rson);
else if(r<=mid)
return query(l,r,lson);
else
{
int ret = max(query(l,mid,lson),query(mid+1,r,rson));
if(tree[lson].rc==tree[rson].lc)
{
int ll = min(tree[lson].rs,tree[lson].r-l+1);
int rr = min(tree[rson].ls,r-tree[rson].l+1);
ret = max(ret,ll+rr);
}
return ret;
}
}
int main()
{
int cas,kcas=0;
scanf("%d",&cas);
while(cas--)
{
int n,c,q;
scanf("%d%d%d",&n,&c,&q);
build(1,n,1);
printf("Case %d:\n",++kcas);
while(q--)
{
int l,r;
scanf("%d%d",&l,&r);
int ans = query(l,r,1);
printf("%d\n",ans);
}
}
return 0;
}