LightOJ-1399-线段树求区间相同颜色连续的最大长度

来源:互联网 发布:48口网络交换机报价 编辑:程序博客网 时间:2024/05/21 06:21

题目大意:区间相同颜色连续的最大长度

题目解析:线段树节点保存左右端点颜色,从左右开始的最大长度和答案,pushup和query的时候考虑左儿子右端点和右儿左端点的颜色是否一样需要特判;

AC代码:

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<string>#define lson rt<<1#define rson rt<<1|1using 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;}



阅读全文
0 0