此题不难却易出错,很能考察思维的严谨性。
指定ll为区间内左端顶格数的连续可利用房间,rr为右端顶格数的数值,mm为区间内最长的连续可利用房间数。
在查询的时候,由于要返回最靠左的区间左端点,使得在该点右侧有长为l的可利用房间数。
那么首先有解存在当且仅当区间mm值大于等于给定长度l。
考虑区间左端点可能落在左区间也可能落在右区间。
横跨区间中点的情形特别要小心,我就是在这wa了几次。
http://poj.org/problem?id=3667
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define lson (u << 1) 5 #define rson (u << 1 | 1) 6 using namespace std; 7 typedef __int64 LL; 8 const int maxn = 5e4 + 10; 9 struct Seg{ 10 int l, r; 11 int lazy; 12 int ll, mm, rr;//vacant rooms 13 }seg[maxn << 2]; 14 int n, m, ans; 15 16 void build(int u, int l, int r){ 17 seg[u].l = l, seg[u].r = r, seg[u].lazy = 0; 18 seg[u].mm = seg[u].ll = seg[u].rr = r - l; 19 if(r - l < 2) return; 20 int mid = (l + r) >> 1; 21 build(lson, l, mid); 22 build(rson, mid, r); 23 } 24 25 void push_down(int u){ 26 if(seg[u].lazy != 0 && seg[u].r - seg[u].l > 1){ 27 if(seg[u].lazy == -1){ 28 seg[lson].lazy = seg[rson].lazy = -1; 29 seg[lson].mm = seg[lson].rr = seg[lson].ll = seg[lson].r - seg[lson].l; 30 seg[rson].mm = seg[rson].rr = seg[rson].ll = seg[rson].r - seg[rson].l; 31 seg[u].lazy = 0; 32 }else if(seg[u].lazy == 1){ 33 seg[lson].lazy = seg[rson].lazy = 1; 34 seg[lson].mm = seg[lson].rr = seg[lson].ll = 0; 35 seg[rson].mm = seg[rson].rr = seg[rson].ll = 0; 36 seg[u].lazy = 0; 37 } 38 } 39 } 40 41 void push_up(int u){ 42 seg[u].mm = max(seg[lson].rr + seg[rson].ll, seg[lson].mm); 43 seg[u].mm = max(seg[u].mm, seg[rson].mm); 44 seg[u].ll = seg[lson].ll == seg[lson].r - seg[lson].l ? seg[lson].ll + seg[rson].ll : seg[lson].ll; 45 seg[u].rr = seg[rson].rr == seg[rson].r - seg[rson].l ? seg[rson].rr + seg[lson].rr : seg[rson].rr; 46 } 47 48 void query(int u, int l, int r, int p){ 49 if(seg[u].mm < p || ans != -1) return; 50 if(seg[u].ll >= p){ 51 ans = seg[u].l; 52 return; 53 } 54 push_down(u); 55 int mid = (l + r) >> 1; 56 if(seg[lson].mm >= p) query(lson, l, mid, p); 57 else if(seg[lson].rr + seg[rson].ll >= p) ans = mid - seg[lson].rr; 58 else query(rson, mid, r, p); 59 } 60 61 void update(int u, int l, int r, int L, int R, int sg){ 62 if(l == L && R == r){ 63 if(sg == -1){ 64 seg[u].mm = seg[u].rr = seg[u].ll = r - l; 65 seg[u].lazy = -1; 66 }else if(sg == 1){ 67 seg[u].mm = seg[u].rr = seg[u].ll = 0; 68 seg[u].lazy = 1; 69 } 70 return; 71 } 72 push_down(u); 73 int mid = (l + r) >> 1; 74 if(R <= mid) update(lson, l, mid, L, R, sg); 75 else if(L >= mid) update(rson, mid, r, L, R, sg); 76 else{ 77 update(lson, l, mid, L, mid, sg); 78 update(rson, mid, r, mid, R, sg); 79 } 80 push_up(u); 81 } 82 83 int main(){ 84 freopen("in.txt", "r", stdin); 85 while(~scanf("%d%d", &n, &m)){ 86 build(1, 1, n + 1); 87 for(int i = 0, u, v, op; i < m; i++){ 88 scanf("%d", &op); 89 if(op == 1){ 90 scanf("%d", &u); 91 ans = -1; 92 query(1, 1, n + 1, u); 93 printf("%d ",ans == -1 ? 0 : ans); 94 if(ans != -1) update(1, 1, n + 1, ans, ans + u, 1); 95 }else if(op == 2){ 96 scanf("%d%d", &u, &v); 97 update(1, 1, n + 1, u, u + v, -1); 98 } 99 } 100 } 101 return 0; 102 }