您的位置:首页 > 其它

poj3667 Hotel

2015-09-26 16:51 232 查看
此题不难却易出错,很能考察思维的严谨性。

指定ll为区间内左端顶格数的连续可利用房间,rr为右端顶格数的数值,mm为区间内最长的连续可利用房间数。

在查询的时候,由于要返回最靠左的区间左端点,使得在该点右侧有长为l的可利用房间数。

那么首先有解存在当且仅当区间mm值大于等于给定长度l。

考虑区间左端点可能落在左区间也可能落在右区间。

横跨区间中点的情形特别要小心,我就是在这wa了几次。
http://poj.org/problem?id=3667
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson (u << 1)
#define rson (u << 1 | 1)
using namespace std;
typedef __int64 LL;
const int maxn = 5e4 + 10;
struct Seg{
int l, r;
int lazy;
int ll, mm, rr;//vacant rooms
}seg[maxn << 2];
int n, m, ans;

void build(int u, int l, int r){
seg[u].l = l, seg[u].r = r, seg[u].lazy = 0;
seg[u].mm = seg[u].ll = seg[u].rr = r - l;
if(r - l < 2) return;
int mid = (l + r) >> 1;
build(lson, l, mid);
build(rson, mid, r);
}

void push_down(int u){
if(seg[u].lazy != 0 && seg[u].r - seg[u].l > 1){
if(seg[u].lazy == -1){
seg[lson].lazy = seg[rson].lazy = -1;
seg[lson].mm = seg[lson].rr = seg[lson].ll = seg[lson].r - seg[lson].l;
seg[rson].mm = seg[rson].rr = seg[rson].ll = seg[rson].r - seg[rson].l;
seg[u].lazy = 0;
}else if(seg[u].lazy == 1){
seg[lson].lazy = seg[rson].lazy = 1;
seg[lson].mm = seg[lson].rr = seg[lson].ll = 0;
seg[rson].mm = seg[rson].rr = seg[rson].ll = 0;
seg[u].lazy = 0;
}
}
}

void push_up(int u){
seg[u].mm = max(seg[lson].rr + seg[rson].ll, seg[lson].mm);
seg[u].mm = max(seg[u].mm, seg[rson].mm);
seg[u].ll = seg[lson].ll == seg[lson].r - seg[lson].l ? seg[lson].ll + seg[rson].ll : seg[lson].ll;
seg[u].rr = seg[rson].rr == seg[rson].r - seg[rson].l ? seg[rson].rr + seg[lson].rr : seg[rson].rr;
}

void query(int u, int l, int r, int p){
if(seg[u].mm < p || ans != -1) return;
if(seg[u].ll >= p){
ans = seg[u].l;
return;
}
push_down(u);
int mid = (l + r) >> 1;
if(seg[lson].mm >= p) query(lson, l, mid, p);
else if(seg[lson].rr + seg[rson].ll >= p) ans = mid - seg[lson].rr;
else query(rson, mid, r, p);
}

void update(int u, int l, int r, int L, int R, int sg){
if(l == L && R == r){
if(sg == -1){
seg[u].mm = seg[u].rr = seg[u].ll = r - l;
seg[u].lazy = -1;
}else if(sg == 1){
seg[u].mm = seg[u].rr = seg[u].ll = 0;
seg[u].lazy = 1;
}
return;
}
push_down(u);
int mid = (l + r) >> 1;
if(R <= mid) update(lson, l, mid, L, R, sg);
else if(L >= mid) update(rson, mid, r, L, R, sg);
else{
update(lson, l, mid, L, mid, sg);
update(rson, mid, r, mid, R, sg);
}
push_up(u);
}

int main(){
freopen("in.txt", "r", stdin);
while(~scanf("%d%d", &n, &m)){
build(1, 1, n + 1);
for(int i = 0, u, v, op; i < m; i++){
scanf("%d", &op);
if(op == 1){
scanf("%d", &u);
ans = -1;
query(1, 1, n + 1, u);
printf("%d\n",ans == -1 ? 0 : ans);
if(ans != -1) update(1, 1, n + 1, ans, ans + u, 1);
}else if(op == 2){
scanf("%d%d", &u, &v);
update(1, 1, n + 1, u, u + v, -1);
}
}
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: