hdu2871Memory Control(线段树区间合并+区间修改)


题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2871

这个题目与线段树区间合并的模板题(链接:点这里)非常相似,就是复杂了一点;

  1 #include
  2 #include
  3 #include
  4 #include
  5 #include
  6 #include
  7 #include<set>
  8 #include
  9 #include
 10 #include
 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 struct section {
163     int st, end;
164     bool operator <(const section& b)const {
165         return st < b.st;
166     }
167 };
168 
169 vector
vec; 170 171 bool cmp(section a, section b) { 172 if (a.st <= b.st) return true; 173 else return false; 174 } 175 176 int FindPos(int x, int l, int r) { 177 178 int pos = -1; 179 int lx = l, rx = r; 180 while (lx <= rx) { 181 int mid = (lx + rx) >> 1; 182 if (x >= vec[mid].st) { 183 pos = mid; 184 lx = mid + 1; 185 } 186 else { 187 rx = mid - 1; 188 } 189 } 190 if (vec[pos].st > x || vec[pos].end < x) { 191 return -1; 192 } 193 else return pos; 194 } 195 196 int main() { 197 198 /*ios::sync_with_stdio(false); 199 cin.tie(0);*/ 200 int n, m; 201 while (~scanf("%d %d", &n, &m)) { 202 Build(1, n, 1); 203 for (int i = 1; i <= m; i++) { 204 char op[10]; 205 int x; 206 scanf("%s", op); 207 if (op[0] == 'N') { 208 scanf("%d", &x); 209 int pos = Query(x, 1, n, 1); 210 if (pos != 0) { 211 //vec.push_back({ pos,pos + x - 1 }); 212 section t; 213 t.st = pos, t.end = pos + x - 1; 214 vector
::iterator it; 215 it = upper_bound(vec.begin(), vec.end(), t); 216 vec.insert(it, t); 217 Update_in(pos, pos + x - 1, 1, n, 1); 218 //cout << "New at " << pos << "\n"; 219 printf("New at %d\n", pos); 220 } 221 else printf("Reject New\n"); 222 //cout << "Reject New" << "\n"; 223 } 224 else if (op[0] == 'F') { 225 scanf("%d", &x); 226 //sort(vec.begin(), vec.end(), cmp); 227 int pos = -1; 228 //int pos = upper_bound(vec.begin(), vec.end(), x) - vec.begin(); 229 int l = 0, r = vec.size() - 1; 230 pos = FindPos(x, l, r); 231 if (pos == -1) { 232 //cout << "Reject Free" << "\n"; 233 printf("Reject Free\n"); 234 } 235 else { 236 Update_out(vec[pos].st, vec[pos].end, 1, n, 1); 237 vector
::iterator it; 238 it = vec.begin() + pos; 239 printf("Free from %d to %d\n", vec[pos].st, vec[pos].end); 240 //cout << "Free from " << vec[pos].st << " to " << vec[pos].end << "\n"; 241 vec.erase(it); 242 } 243 } 244 else if (op[0] == 'G') { 245 scanf("%d", &x); 246 if (x > vec.size()) { 247 //cout << "Reject Get" << "\n"; 248 printf("Reject Get\n"); 249 continue; 250 } 251 //sort(vec.begin(), vec.end(), cmp); 252 //cout << "Get at " << vec[x - 1].st << "\n"; 253 printf("Get at %d\n", vec[x - 1].st); 254 } 255 else { 256 Update_out(1, n, 1, n, 1); 257 vec.clear(); 258 //cout << "Reset Now" << "\n"; 259 printf("Reset Now\n"); 260 } 261 /*cout << "---------------------------------" << "\n"; 262 for (int i = 0; i < vec.size(); i++) { 263 cout << vec[i].st << " " << vec[i].end << "\n"; 264 } 265 cout << "---------------------------------" << "\n";*/ 266 } 267 putchar('\n'); 268 vec.clear(); 269 memset(tree, 0, sizeof(tree)); 270 } 271 272 return 0; 273 }