poj3667Hotel(线段树区间合并)

题目链接:http://poj.org/problem?id=3667

题目大意:给你一排n个房间,你有两种操作,1操作是占据x个房间,尽量往左占(也就是第一个编号尽可能小),空房间不够输出0,2操作是让你释放从x到x+y-1的房间,让他们成为空房间。

这道题是线段树区间合并的典型例题,我为了解决这道题花费了两三天的时间(其实大部分时间都在摸鱼QAQ),在此期间我找了很多的博客去学习,结果不尽人意,就在我苦思冥想该怎么办的时候,突发奇想去b站了搜了一波,结果发现了一个宝藏视频,视频链接(我在想有没有一种可能是我前几天看的博客,在今天晚上厚积薄发了,但这个视频雀氏不错),之后我在看完这个视频后就顿悟了,hh,挺开心的,我想,这就是算法竞赛的乐趣之一吧。

ac代码:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<vector>
  5 #include<map>
  6 #include<queue>
  7 #include<set>
  8 #include<cmath>
  9 #include<list>
 10 #include<cstring>
 11 #include<string>
 12 #define ll long long
 13 #define ull unsigned long long
 14 #define inf 0x3f3f3f3f
 15 #define inff 0x7fffffff
 16 using namespace std;
 17 const int N = 50000 + 10;
 18 const int M = 1000000 + 10;
 19 const ll mod = 1e9 + 7;
 20 
 21 struct node {
 22     int lsum;
 23     int rsum;
 24     int sum;
 25     int lazy;
 26     int len;
 27 }tree[N << 2];
 28 
 29 void PushUp(int rt) {
 30 
 31     if (tree[rt << 1].sum == tree[rt << 1].len) {
 32         tree[rt].lsum = tree[rt << 1].sum + tree[rt << 1 | 1].lsum;
 33     }
 34     else {
 35         tree[rt].lsum = tree[rt << 1].lsum;
 36     }
 37     if (tree[rt << 1 | 1].sum == tree[rt << 1 | 1].len) {
 38         tree[rt].rsum = tree[rt << 1 | 1].sum + tree[rt << 1].rsum;
 39     }
 40     else {
 41         tree[rt].rsum = tree[rt << 1 | 1].rsum;
 42     }
 43     tree[rt].sum = tree[rt << 1].rsum + tree[rt << 1 | 1].lsum;
 44     tree[rt].sum = max(tree[rt << 1].sum, tree[rt].sum);
 45     tree[rt].sum = max(tree[rt << 1 | 1].sum, tree[rt].sum);
 46 
 47     return;
 48 }
 49 
 50 void Build(int l, int r, int rt) {
 51 
 52     tree[rt].len = r - l + 1;
 53     if (l == r) {
 54         tree[rt].sum = tree[rt].lsum = tree[rt].rsum = 1;
 55         return;
 56     }
 57     int mid = (l + r) >> 1;
 58     Build(l, mid, rt << 1);
 59     Build(mid + 1, r, rt << 1 | 1);
 60     PushUp(rt);
 61 
 62     return;
 63 }
 64 
 65 void PushDown(int l, int r, int rt) {
 66 
 67     if (tree[rt].lazy == 0) return;
 68     int mid = (l + r) >> 1;
 69     if (tree[rt].lazy == 1) {
 70         tree[rt << 1].sum = tree[rt << 1].lsum = tree[rt << 1].rsum = 0;
 71         tree[rt << 1 | 1].sum = tree[rt << 1 | 1].lsum = tree[rt << 1 | 1].rsum = 0;
 72         tree[rt << 1].lazy = tree[rt << 1 | 1].lazy = 1;
 73     }
 74     else {
 75         tree[rt << 1].sum = tree[rt << 1].lsum = tree[rt << 1].rsum = mid - l + 1;
 76         tree[rt << 1 | 1].sum = tree[rt << 1 | 1].lsum = tree[rt << 1 | 1].rsum = r - (mid + 1) + 1;
 77         tree[rt << 1].lazy = tree[rt << 1 | 1].lazy = 2;
 78     }
 79     tree[rt].lazy = 0;
 80 
 81     return;
 82 }
 83 
 84 void Update_in(int L, int R, int l, int r, int rt) {
 85 
 86     if (l >= L && r <= R) {
 87         tree[rt].sum = tree[rt].lsum = tree[rt].rsum = 0;
 88         tree[rt].lazy = 1;
 89         return;
 90     }
 91     PushDown(l, r, rt);
 92     int mid = (l + r) >> 1;
 93     if (L <= mid) Update_in(L, R, l, mid, rt << 1);
 94     if (R > mid) Update_in(L, R, mid + 1, r, rt << 1 | 1);
 95     PushUp(rt);
 96 
 97     return;
 98 }
 99 
100 void Update_out(int L, int R, int l, int r, int rt) {
101 
102     if (l >= L && r <= R) {
103         tree[rt].sum = tree[rt].lsum = tree[rt].rsum = r - l + 1;
104         tree[rt].lazy = 2;
105         return;
106     }
107     PushDown(l, r, rt);
108     int mid = (l + r) >> 1;
109     if (L <= mid) Update_out(L, R, l, mid, rt << 1);
110     if (R > mid) Update_out(L, R, mid + 1, r, rt << 1 | 1);
111     PushUp(rt);
112 
113     return;
114 }
115 
116 //void PointUpdate(int L, int l, int r, int rt) {
117 //
118 //    if (l == r) {
119 //        sum[rt]++;
120 //        return;
121 //    }
122 //    int mid = (l + r) >> 1;
123 //    if (L <= mid) PointUpdate(L, l, mid, rt << 1);
124 //    else PointUpdate(L, mid + 1, r, rt << 1 | 1);
125 //    PushUp(rt);
126 //
127 //    return;
128 //}
129 
130 int Query(int len, int l, int r, int rt) {
131 
132     if (l == r) return l;
133     int mid = (l + r) >> 1;
134     PushDown(l, r, rt);
135     if (tree[rt << 1].sum >= len) {
136         return Query(len, l, mid, rt << 1);
137     }
138     if (tree[rt << 1].rsum + tree[rt << 1 | 1].lsum >= len) {
139         return mid - tree[rt << 1].rsum + 1;
140     }
141     if (tree[rt << 1 | 1].sum >= len) {
142         return Query(len, mid + 1, r, rt << 1 | 1);
143     }
144 
145     return 0;
146 }
147 
148 //int Query(int L, int R, int l, int r, int rt) {
149 //
150 //    if (l >= L && r <= R) {
151 //        return sum[rt];
152 //    }
153 //    int mid = (l + r) >> 1;
154 //
155 //    int ans = 0;
156 //    if (L <= mid) ans += Query(L, R, l, mid, rt << 1);
157 //    if (R > mid) ans += Query(L, R, mid + 1, r, rt << 1 | 1);
158 //
159 //    return ans;
160 //}
161 
162 int main() {
163 
164     ios::sync_with_stdio(false);
165     cin.tie(0);
166     int n, m;
167     cin >> n >> m;
168     Build(1, n, 1);
169     for (int i = 1; i <= m; i++) {
170         int op, x, y;
171         cin >> op;
172         if (op == 1) {
173             cin >> x;
174             int pos = Query(x, 1, n, 1);
175             if (pos != 0) Update_in(pos, pos + x - 1, 1, n, 1);
176             cout << pos << "\n";
177         }
178         else {
179             cin >> x >> y;
180             Update_out(x, x + y - 1, 1, n, 1);
181         }
182     }
183 
184     return 0;
185 }

 

 
posted @ 2022-04-28 20:41  Keyzee  阅读(33)  评论(0)    收藏  举报