HZAU 1207 Candies(线段树区间查询 区间修改)

【题目链接】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+;
const int N=1e6+;
int n,m,k,L,R,V;
char s[N];
int lazy[N<<];
struct Tree{
int l,r,maxn,len;
}a[N<<];
void pushdwn(int pos,int len){
if(lazy[pos]!=-){
lazy[pos<<]=lazy[pos<<|]=lazy[pos];
a[pos<<].l=a[pos<<].r=a[pos<<].maxn=lazy[pos]?len-(len>>):;
a[pos<<|].l=a[pos<<|].r=a[pos<<|].maxn=lazy[pos]?(len>>):;
lazy[pos]=-;
}
}
void pushup(int pos,int len){
a[pos].l=a[pos<<].l;
a[pos].r=a[pos<<|].r;
if(a[pos].l==len-(len>>))a[pos].l+=a[pos<<|].l;
if(a[pos].r==(len>>))a[pos].r+=a[pos<<].r;
a[pos].maxn=max(a[pos<<].r+a[pos<<|].l,max(a[pos<<].maxn,a[pos<<|].maxn));
}
void build(int pos,int l,int r){
lazy[pos]=-;
if(l==r){
a[pos].l=a[pos].r=a[pos].maxn=(s[l]=='B')?:;
return;
}
int mid=(l+r)>>;
build(pos<<,l,mid);
build(pos<<|,mid+,r);
pushup(pos,r-l+);
}
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+:;
lazy[pos]=V;
return;
}
pushdwn(pos,r-l+);
int mid=(l+r)>>;
if(L<=mid)update(pos<<,l,mid);
if(R>mid)update(pos<<|,mid+,r);
pushup(pos,r-l+);
}
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+;
return a[pos];
}
pushdwn(pos,r-l+);
int mid=(l+r)>>;
if(mid>=R)return query(pos<<,l,mid);
if(mid<L)return query(pos<<|,mid+,r);
Tree t1=query(pos<<,l,mid),t2=query(pos<<|,mid+,r);
return merg(t1,t2);
}
int main()
{
int t;
scanf("%d",&t);
for(int cas=;cas<=t;cas++)
{
memset(a,,sizeof a);
printf("Case #%d:\n",cas);
scanf("%d%d%s",&n,&m,s+);
build(,,n);
int p;
while(m--)
{
scanf("%d%d%d",&p,&L,&R);
if(p==)
{
scanf("%d",&V);
V--;
update(,,n);
}
else printf("%d\n",query(,,n).maxn);
}
}
return ;
}
上一篇:HDU 1698 【线段树,区间修改 + 维护区间和】


下一篇:Android混淆打包