区间合并
说一道例题:poj3667
题意: 两种操作:
1 s 查询有没有连续为s的区间有的话输出最左端的那个位置并把那个区间里的值都减了
2 a s 左端为a长度为s的房间退房 也就是a~a+s-1这个区间值都加一
考虑怎么做。。
可以给线段树里放一个lnum,rnum,num分别代表左边连续最大,右边连续最大,总的连续最大,的空房,然后up的时候当前的lnum就等于左边的lnum;当前的rnum就等于右儿子的rnum;num就等于目前的和 左儿子的 和 右儿子的 和 左儿子的右加右儿子 的左最大值;这里注意计算lnum和rnum的时候 如果左儿子里的区间是满的然后 lnum就不是左儿子的lnum了,还得加一个右儿子的lnum。然后rnum同理,这里一定不能忘了!
代码
#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxn = 50006;
struct Node
{
int l,r,lnum,rnum,num,tag;
}node[maxn<<2];
void build(int l,int r,int no)
{
node[no].l=l;
node[no].r=r;
node[no].num=node[no].lnum=node[no].rnum=r-l+1;
node[no].tag=0;
if(l==r)
return;
int mid=l+r>>1;
build(l,mid,no<<1);
build(mid+1,r,no<<1|1);
}
void down(int no)
{
if(node[no].tag==-1)
{
node[no<<1].num=node[no<<1].lnum=node[no<<1].rnum=0;
node[no<<1|1].num