很长时间没写过分段的线段树了,自己开始一看也感觉一头雾水,但是最长的长度分为左最长,最长和右最长这是一开始就必须清楚的,分段更新我也不太熟悉,看了下别人的博客,感觉思路很清晰,敲出来,最后2个数据怎么搞都是错的,整整改了2个小时,最后看着别人的代码一句一句的对着看,终于发现自己看掉了一种情况,记事在左右结点的状态改变后,父节点也需要按条件进行改变。也就是upDate中的
if(node[L(u)].f == node[R(u)].f)
node[u].f = node[R(u)].f;
#include<cstdio>
#include<cstring>
#include<iostream>
#define L(u) (u<<1)
#define R(u) (u<<1|1)
using namespace std;
const int N = 16010;
struct Node {
int l,r;
int lma, ma, rma, f;
}node[N<<2];
int Max(int a,int b)
{
return a>b?a:b;
}
void pushDown(int u,int c)//往下一层进行更新操作
{
node[u].f = 0;
node[L(u)].f = c;
node[R(u)].f = c; //左右继续保持原状,便于继续进行更新
if(c == 1)
{
node[L(u)].lma = node[L(u)].ma = node[L(u)].rma = 0;
node[R(u)].lma = node[R(u)].ma = node[R(u)].rma = 0;
}
else
{
node[L(u)].lma = node[L(u)].ma = node[L(u)].rma = node[L(u)].r - node[L(u)].l + 1;
node[R(u)].lma = node[R(u)].ma = node[R(u)].rma = node[R(u)].r - node[R(u)].l + 1;
}
}
void build(int u,int left,int right)
{
node[u].l = left, node[u].r = right;
if(node[u].l==node[u].r)
{
return;
}
int mid = (node[u].l+node[u].r)>>1;
build(L(u),left,mid);
build(R(u),mid+1,right);
}
void upDate(int u,int left,int right,int c)
{
if(left<=node[u].l&&node[u].r<=right)
{
node[u].f = c;
if(c == 1)
{
node[u].lma = node[u].ma = node[u].rma = 0;
}
else
{
node[u].lma = node[u].ma = node[u].rma = node[u].r - node[u].l + 1;
}
return;
}
if(c == node[u].f)
return;
if(-1*c == node[u].f)
{
pushDown(u, node[u].f);
}
int mid = (node[u].l+node[u].r)>>1;
if(right<=mid)
upDate(L(u),left,right,c);
else if(left>mid)
upDate(R(u),left,right,c);
else
{
upDate(L(u),left,mid,c);
upDate(R(u),mid+1,right,c);
}
//这里需要对父节点的信息进行更新
if(node[L(u)].f == -1)
{
node[u].lma = node[L(u)].ma + node[R(u)].lma;
}
else
{
node[u].lma = node[L(u)].lma;
}
if(node[R(u)].f == -1)
{
node[u].rma = node[R(u)].ma + node[L(u)].rma;
}
else
{
node[u].rma = node[R(u)].rma;
}
int a = node[L(u)].rma + node[R(u)].lma;
int b = Max(node[L(u)].ma, node[R(u)].ma);
int g = Max(node[u].lma, node[u].rma);
node[u].ma = Max(Max(a,b),g);
if(node[L(u)].f == node[R(u)].f)
node[u].f = node[R(u)].f;
}
int main(void)
{
int n, m, x, y, z;
scanf("%d%d",&n,&m);
build(1, 1, n);
node[1].f = -1;
node[1].ma = n;
while(m--)
{
scanf("%d",&x);
if(x == 1)
{
scanf("%d%d",&y,&z);
upDate(1, y, y+z-1, 1);
}
else if(x == 2)
{
scanf("%d%d",&y,&z);
upDate(1, y, y+z-1, -1);
}
else
{
cout<<node[1].ma<<endl;
}
}
return 0;
}