代码写得比较乱。
区间最长连续黑色:maxb
区间最长连续白色:maxw
区间左端点颜色:lcolor
区间右端点颜色:rcolor
左端点起最长连续数:lmax
右端点起最长连续数:rmax
标记区间是否被更改过:flag
#include<iostream>
using namespace std;
struct tree
{
int left;
int right;
int maxb,maxw;
int lcolor,rcolor;
int lmax,rmax;
int flag;
}t[400000];
inline int max(int a,int b)
{
return a>b? a:b;
}
inline int min(int a,int b)
{
return a>b? b:a;
}
int key[100005];
void create(int l,int r,int now);
void add_node(int now);
void update_node(int now);
void update_tree(int l,int r,int now);
void change_node(int now);
int query(int l,int r,int now);
int main()
{
int n,m,x,l,r,ans;
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&key[i]);
}
create(1,n,1);
add_node(1);
cin>>m;
while(m--)
{
scanf("%d%d%d",&x,&l,&r);
if(x==0)
{
ans=query(l,r,1);
printf("%d\n",ans);
}
else
update_tree(l,r,1);
}
}
return 0;
}
void create(int l,int r,int now)
{
t[now].left=l;
t[now].right=r;
t[now].lmax=0;
t[now].rmax=0;
t[now].maxb=0;
t[now].maxw=0;
t[now].rcolor=0;
t[now].lcolor=0;
t[now].flag=0;
if(l<r)
{
int mid=(r+l)>>1;
create(l,mid,now<<1);
create(mid+1,r,(now<<1)+1);
}
return;
}
void add_node(int now)
{
if(t[now].left==t[now].right)
{
t[now].lcolor=t[now].rcolor=key[t[now].left];
t[now].lmax=t[now].rmax=1;
t[now].maxb=key[t[now].left];
t[now].maxw=1-key[t[now].left];
t[now].flag=0;
return ;
}
add_node(now<<1);
add_node( (now<<1)+1 );
update_node(now);
return ;
}
void update_node(int now)
{
int left=now<<1,right=(now<<1)+1;
t[now].lcolor=t[left].lcolor;
t[now].rcolor=t[right].rcolor;
if(t[left].lmax==t[left].right-t[left].left+1 && t[left].rcolor==t[right].lcolor)
t[now].lmax=t[left].lmax+t[right].lmax;
else
t[now].lmax=t[left].lmax;
if(t[right].rmax==t[right].right-t[right].left+1 && t[right].lcolor==t[left].rcolor)
t[now].rmax=t[right].rmax+t[left].rmax;
else
t[now].rmax=t[right].rmax;
t[now].maxb=max(t[right].maxb,t[left].maxb);
t[now].maxw=max(t[right].maxw,t[left].maxw);
if(t[left].rcolor==t[right].lcolor)
{
if(t[left].rcolor==1)
t[now].maxb=max(t[now].maxb,t[left].rmax+t[right].lmax);
else if(t[left].rcolor==0)
t[now].maxw=max(t[now].maxw,t[left].rmax+t[right].lmax);
}
}
void update_tree(int l,int r,int now)
{
if(t[now].left==l && t[now].right==r)
{
change_node(now);
return ;
}
if(t[now].flag==1)
{
change_node(now<<1);
change_node( (now<<1) +1);
t[now].flag=0;
}
int mid=(t[now].left+t[now].right)>>1;
if(r<=mid)
update_tree(l,r,now<<1);
else if(l>mid)
update_tree(l,r,(now<<1)+1);
else
{
update_tree(l,mid,now<<1);
update_tree(mid+1,r,(now<<1)+1);
}
update_node(now);
}
void change_node(int now)
{
t[now].lcolor=t[now].lcolor^1;
t[now].rcolor=t[now].rcolor^1;
t[now].maxb=t[now].maxb^t[now].maxw;
t[now].maxw=t[now].maxb^t[now].maxw;
t[now].maxb=t[now].maxb^t[now].maxw;
t[now].flag=t[now].flag^1;
}
int query(int l,int r,int now)
{
if(t[now].left==l && t[now].right==r)
return t[now].maxb;
if(t[now].flag==1)
{
change_node(now<<1);
change_node( (now<<1)+1 );
t[now].flag=0;
}
int mid=(t[now].left+t[now].right)>>1;
// int left=now<<1,right=(now<<1)+1;
int t1=0,t2=0,t3=0,t4=0,t5=0;
if(r<=mid)
t1=query(l,r,now<<1);
else if(l>mid)
t2=query(l,r,(now<<1)+1);
else
{
t3=query(l,mid,now<<1);
t4=query(mid+1,r,(now<<1)+1);
if(t[now<<1].rcolor==1 && t[ (now<<1)+1 ].lcolor==1)
t5=min(mid-l+1,t[now<<1].rmax)+min(r-mid,t[ (now<<1)+1].lmax);
}
update_node(now);
return max( max( max(t1,t2),max(t3,t4) ) , t5);
}
分享到:
相关推荐
hdu 1166线段树代码
hdu 1166线段树
【hdu5306】Gorgeous Sequence 线段树区间最值操作-附件资源
从简单入门到偏中等的几个题,线段树很灵活,主要懂了lazy操作,其他的自己yy吧。
线段树入门资料,有利于初学者学习,让他们详细了解线段树。
NULL 博文链接:https://128kj.iteye.com/blog/1738772
大量线段树题目 zoj 1610 线段覆盖 poj 2777 线段覆盖 poj 2528 需要离散化,建树不同,需要处理不同->注意这组数据 3 1 10 1 3 6 10 the ans is 3. hdu 1754 求区间最大值 hdu 1166 求区间和 hdu 1698 成段更新 ...
题面 【题目描述】 有nnn个营地,已知每个营地的人数,有四条命令: (1)Add(1) Add(1)Add iii jjj,iii和jjj为正整数,表示第iii个营地增加jjj个人(jjj不超过303030) (2)Sub(2)Sub(2)Sub iii jjj ,iii和jjj为正...
300+ AC 代码 。 大数 , 线段树 , 字符串 , dp.....
HDU的1250,主要是利用高精度加法,但是代码有点繁琐,效率不是很高
杭电ACMhdu1163
HDU1059的代码
hdu1001解题报告
hdu 1574 passed sorce
HDU的一题........HDU DP动态规
hdu2101AC代码
hdu acm 教案 搜索入门 hdu acm 教案 搜索入门
搜索 dfs 解题代码 hdu1241
hdu 5007 Post Robot 字符串枚举。 暴力一下就可以了。