[转]poj 1823 Hotel 线段树

线段树。
题意是给出一个长为N的区间,不断进行三中操作:
1.插入一个区间,所有被插入的地方都表示占有;
2.删除一个区间,所有删除的地方都表示释放;
3.询问整个范围内最长的连续的空区间的长度。
很明显的线段树,可惜我想错了,以为入区间的最大值可以独立的从两个子区间中寻找,忘记了两个子区间合并后可能得到一个更长的区间,尝试好多数据都对,提交就是WA,看网上的做法跟我的差别很大,也没心情看。搁置了好几天,今天终于发现原来自己从开始就把算法想错了,而不是代码的问题,白查了那么久,理解还是不够深啊。

 

#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<queue>
#include<stack>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<fstream>
#include<sstream>
#include<iomanip>
using namespace std;
const int N = 16001;
const int M = 101;
const int MAX = 1000000000;
struct node
{
int l,r;//denotes the bound of the segment
int la,ra,ma;//denotes the the bound of max free segment in this segment
int f;//denotes if the segment is 2 full used or 0 free or 1 partial used
}t[4*N];
void build(int i, int l, int r)
{
t[i].l = l;
t[i].r = r;
t[i].f = 0;
if(l == r)return;
int mid = (l+r)>>1;
build(i<<1, l, mid);
build((i<<1)+1, mid+1, r);
}
void insert(int i, int l, int r)
{
if(t[i].l == l && t[i].r == r)
{
t[i].f = 2;
t[i].ma = t[i].la = t[i].ra = 0;
return;
}
int x;
if(t[i].f == 0)
{
x = (i<<1);
t[i].f = 1;
t[x].f = 0;
t[x+1].f = 0;
t[x].la = t[x].ma = t[x].ra = t[x].r-t[x].l+1;
x++;
t[x].la = t[x].ma = t[x].ra = t[x].r-t[x].l+1;
}
int mid = (t[i].l + t[i].r)>>1;
if(r <= mid)
{
insert(i<<1, l, r);
}
else if(l > mid)
{
insert((i<<1)+1, l, r);
}
else
{
insert(i<<1, l, mid);
insert((i<<1)+1, mid+1, r);
}
//the key oprations
x = i<<1;
if(t[x].f == 0)
{
t[i].la = t[x].ma + t[x+1].la;
}
else
{
t[i].la = t[x].la;
}
x++;
if(t[x].f == 0)
{
t[i].ra = t[x-1].ra + t[x].ma;
}
else
{
t[i].ra = t[x].ra;
}
int a,b,c;
a = max(t[i<<1].ma,t[(i<<1)+1].ma);
b = t[i<<1].ra + t[(i<<1)+1].la;
c = max(t[i].la, t[i].ra);
t[i].ma = max(max(a,b),c);
if(t[i<<1].f == t[(i<<1)+1].f)
{
t[i].f = t[i<<1].f;
}
}
void remove(int i, int l, int r)
{
if(t[i].l == l && t[i].r == r)
{
t[i].f = 0;
t[i].ma = t[i].la = t[i].ra = r-l+1;
return;
}
int x;
if(t[i].f == 2)
{
x = (i<<1);
t[i].f = 1;
t[x].f = 2;
t[x+1].f = 2;
t[x].la = t[x].ma = t[x].ra = 0;
x++;
t[x].la = t[x].ma = t[x].ra = 0;
}
int mid = (t[i].l + t[i].r)>>1;
if(r <= mid)
{
remove(i<<1, l, r);
}
else if(l > mid)
{
remove((i<<1)+1, l, r);
}
else
{
remove(i<<1, l, mid);
remove((i<<1)+1, mid+1, r);
}
//the key oprations
x = i<<1;
if(t[x].f == 0)
{
t[i].la = t[x].ma + t[x+1].la;
}
else
{
t[i].la = t[x].la;
}
x++;
if(t[x].f == 0)
{
t[i].ra = t[x-1].ra + t[x].ma;
}
else
{
t[i].ra = t[x].ra;
}
int a,b,c;
a = max(t[i<<1].ma,t[(i<<1)+1].ma);
b = t[i<<1].ra + t[(i<<1)+1].la;
c = max(t[i].la, t[i].ra);
t[i].ma = max(max(a,b),c);
if(t[i<<1].f == t[(i<<1)+1].f)
{
t[i].f = t[i<<1].f;
}
}
int main()
{
int n,p,c,a,b;
while(scanf("%d%d",&n,&p) != EOF)
{
build(1,1,n);
t[1].f = 0;
t[1].ma = t[1].la = t[1].ra = n;
while(p--)
{
scanf("%d",&c);
if(c == 1)
{
scanf("%d%d",&a,&b);
if(b == 0)continue;
insert(1,a,a+b-1);
}
else if(c == 2)
{
scanf("%d%d",&a,&b);
remove(1,a,a+b-1);
}
else
{
printf("%d\n",t[1].ma);
}
}
}
return 0;
}

 

 

posted @ 2012-07-26 17:52  何解一直犯相同错误?  阅读(141)  评论(0编辑  收藏  举报