HDU 1540 Tunnel Warfare
HDU 4553 约会安排
最大连续区间也是线段树比较套路的做法
维护三个标记
ls,rs,ms
分别表示从当前区间左端点开始的最长连续区间,最长连续区间,右端点开始的最长连续区间
标记主要在push_up中体现
void push_up(int id,int l,int r)
{
tree[id].ml = max(max(tree[id<<1].ml,tree[id<<1|1].ml),tree[id<<1].rl+tree[id<<1|1].ll);
tree[id].ll = tree[id<<1].ll;
if(tree[id<<1].ll == (r+l)/2-l+1) tree[id].ll += tree[id<<1|1].ll;
tree[id].rl = tree[id<<1|1].rl;
if(tree[id<<1|1].rl == r-(r+l)/2) tree[id].rl += tree[id<<1].rl;
}
用左右儿子的三个标记更新父节点的三个标记
首先是ms,显然父节点的ms等于左儿子的ms和右儿子的ms以及左儿子的rs+右儿子的ls这三者的最大值
然后是ls,先把左二子的ls赋给他,再看左二子的ls是否与他的总区间相等,如果相等则再加上右儿子的ls。本质是看左右区间是否连通。
rs同理
HDU 1540 Tunnel Warfare
最大连续区间的裸题
//虽然对线段树的本质有点理解
//但是线段树是个很灵活的数据结构
//进阶一点的就是线段树应该存储什么数据
//如果要维护最大连续区间
//由于二叉树的性质 最大连续区间 的维护离不开 左端最大连续区间 和 右端最大连续区间
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<stack>
using namespace std;
const int maxn = 5e4+5;
int n,m;
struct node
{
int ll,rl,ml;
}tree[maxn<<2];
void push_up(int id,int l,int r)
{
tree[id].ml = max(max(tree[id<<1].ml,tree[id<<1|1].ml),tree[id<<1].rl+tree[id<<1|1].ll);
tree[id].ll = tree[id<<1].ll;
if(tree[id<<1].ll == (r+l)/2-l+1) tree[id].ll += tree[id<<1|1].ll;
tree[id].rl = tree[id<<1|1].rl;
if(tree[id<<1|1].rl == r-(r+l)/2) tree[id].rl += tree[id<<1].rl;
}
void build(int id,int l,int r)
{
tree[id].ll = tree[id].rl = tree[id].ml = r-l+1;
if(l==r) return ;
int mid = (l+r)>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
}
void update(int id,int stl,int str,int x,int c)
{
if(stl==str)
{
tree[id].ll = tree[id].rl = tree[id]