lightoj 1339 Strongest Community 线段树

来源:互联网 发布:手机短信朗读软件 编辑:程序博客网 时间:2024/06/05 09:14

题意:Q次查询区间[l , r]相同连续的最长长度。

思路:线段树。线段树中存5个信息:(1)当前区间的最长长度 (2)左右端的颜色 (3)从左端向右的最长长度 (4)从右端向左的最长长度

查询和向上更新时,需要注意左子树右端和右子树左端颜色相同时候的情况。详见代码:

// file name: lightoj1339.cpp //// author: kereo //// create time:  2014年08月30日 星期六 10时13分03秒 ////***********************************//#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<set>#include<map>#include<vector>#include<stack>#include<cmath>#include<algorithm>using namespace std;typedef long long ll;const int MAXN=100000+100;const int inf=0x3fffffff;#define L(x) (x<<1)#define R(x) (x<<1|1)int n,c,Q;struct node{int l,r;intMax; //[l,r]最大连续的长度int lc,rc; //[l,r]左右端的颜色int ls,rs; //[l,r]左端向右最大连续长度,[l,r]右端向左最大连续长度}segtree[MAXN<<2];void push_up(int rt){segtree[rt].lc=segtree[L(rt)].lc; segtree[rt].rc=segtree[R(rt)].rc;segtree[rt].Max=max(segtree[L(rt)].Max,segtree[R(rt)].Max);segtree[rt].ls=segtree[L(rt)].ls; segtree[rt].rs=segtree[R(rt)].rs;if(segtree[L(rt)].rc == segtree[R(rt)].lc){if(segtree[L(rt)].ls == segtree[L(rt)].r-segtree[L(rt)].l+1)segtree[rt].ls=segtree[L(rt)].ls+segtree[R(rt)].ls;if(segtree[R(rt)].rs == segtree[R(rt)].r-segtree[R(rt)].l+1)segtree[rt].rs=segtree[R(rt)].rs+segtree[L(rt)].rs;int sum=segtree[L(rt)].rs+segtree[R(rt)].ls;segtree[rt].Max=max(segtree[rt].Max,sum);}}void build(int rt,int l,int r){segtree[rt].l=l; segtree[rt].r=r;if(l == r){int x;scanf("%d",&x);segtree[rt].Max=1;segtree[rt].lc=segtree[rt].rc=x;segtree[rt].ls=segtree[rt].rs=1;return ;}int mid=(l+r)>>1;build(L(rt),l,mid); build(R(rt),mid+1,r);push_up(rt);}int query(int rt,int l,int r){if(segtree[rt].l == l && segtree[rt].r == r)return segtree[rt].Max;int mid=(segtree[rt].l+segtree[rt].r)>>1;if(l>mid)return query(R(rt),l,r);else if(r<=mid)return query(L(rt),l,r);else{int ans=max(query(L(rt),l,mid),query(R(rt),mid+1,r));if(segtree[L(rt)].rc == segtree[R(rt)].lc){int sum1=min(segtree[L(rt)].rs,segtree[L(rt)].r-l+1);int sum2=min(segtree[R(rt)].ls,r-segtree[R(rt)].l+1);ans=max(ans,sum1+sum2);}return ans;}}int main(){int T,kase=0;scanf("%d",&T);while(T--){scanf("%d%d%d",&n,&c,&Q);build(1,1,n);printf("Case %d:\n",++kase);while(Q--){int l,r;scanf("%d%d",&l,&r);printf("%d\n",query(1,l,r));}}return 0;}


0 0
原创粉丝点击