【题目链接】http://acm.hzau.edu.cn/problem.php?id=1207
【题意】给你一个字符串,然后两种操作:1,将区间L,R更新为A或者B,2,询问区间L,R最长的连续的B为多长。
【分析】典型线段树,每个节点维护该区间左边连续B的长度,右边连续B的长度,最长的连续B的长度,还有lazy标记。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <stack> #include <map> #include <string> #include <cmath> #include <stdlib.h> using namespace std; typedef long long LL; const int inf=0x3f3f3f3f; const int mod=1e9+7; const int N=1e6+10; int n,m,k,L,R,V; char s[N]; int lazy[N<<2]; struct Tree{ int l,r,maxn,len; }a[N<<2]; void pushdwn(int pos,int len){ if(lazy[pos]!=-1){ lazy[pos<<1]=lazy[pos<<1|1]=lazy[pos]; a[pos<<1].l=a[pos<<1].r=a[pos<<1].maxn=lazy[pos]?len-(len>>1):0; a[pos<<1|1].l=a[pos<<1|1].r=a[pos<<1|1].maxn=lazy[pos]?(len>>1):0; lazy[pos]=-1; } } void pushup(int pos,int len){ a[pos].l=a[pos<<1].l; a[pos].r=a[pos<<1|1].r; if(a[pos].l==len-(len>>1))a[pos].l+=a[pos<<1|1].l; if(a[pos].r==(len>>1))a[pos].r+=a[pos<<1].r; a[pos].maxn=max(a[pos<<1].r+a[pos<<1|1].l,max(a[pos<<1].maxn,a[pos<<1|1].maxn)); } void build(int pos,int l,int r){ lazy[pos]=-1; if(l==r){ a[pos].l=a[pos].r=a[pos].maxn=(s[l]=='B')?1:0; return; } int mid=(l+r)>>1; build(pos<<1,l,mid); build(pos<<1|1,mid+1,r); pushup(pos,r-l+1); } void update(int pos,int l,int r){ if(L<=l&&r<=R){ a[pos].l=a[pos].r=a[pos].maxn=V?r-l+1:0; lazy[pos]=V; return; } pushdwn(pos,r-l+1); int mid=(l+r)>>1; if(L<=mid)update(pos<<1,l,mid); if(R>mid)update(pos<<1|1,mid+1,r); pushup(pos,r-l+1); } Tree merg(Tree t1,Tree t2){ Tree ret; ret.len=t1.len+t2.len; ret.l=t1.l; ret.r=t2.r; if(t1.l==t1.len) ret.l+=t2.l; if(t2.r==t2.len) ret.r+=t1.r; ret.maxn=max(t1.r+t2.l,max(t1.maxn,t2.maxn)); return ret; } Tree query(int pos,int l,int r){ if(L<=l&&r<=R){ a[pos].len=r-l+1; return a[pos]; } pushdwn(pos,r-l+1); int mid=(l+r)>>1; if(mid>=R)return query(pos<<1,l,mid); if(mid<L)return query(pos<<1|1,mid+1,r); Tree t1=query(pos<<1,l,mid),t2=query(pos<<1|1,mid+1,r); return merg(t1,t2); } int main() { int t; scanf("%d",&t); for(int cas=1;cas<=t;cas++) { memset(a,0,sizeof a); printf("Case #%d:\n",cas); scanf("%d%d%s",&n,&m,s+1); build(1,1,n); int p; while(m--) { scanf("%d%d%d",&p,&L,&R); if(p==1) { scanf("%d",&V); V--; update(1,1,n); } else printf("%d\n",query(1,1,n).maxn); } } return 0; }