HDU

题意:

  要求实现一个内存控制器:

  1.New x——申请一片连续的长度为x的内存,返回可申请的最前面一块内存的起点;

  2.Get x——返回第x块占用内存的起点;

  3.Free x——释放地址x所在内存;

  4.Reset——释放全部内存。

  因为在练习splay所以这道线段树神题就写的splay了w。一开始LJY讲了一种 用两棵splay tree来维护:一个用来记录未使用的内存, 另一个是使用的内存。当时他说这样写细节比较少我还没理解什么意思。。

  用一棵splay来做写起来比较短qvq 可是细节好麻烦啊。。一直TLE也未必是常数问题可能是自己写错了,嗯比如说我这样的沙茶读数出问题导致交上去TLE。。然而并不知道为什么于是找了个代码改QAQ 抄代码是不对的以后不能这样了_(:з」∠)_

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <iostream>
  4 #define MaxN 50010
  5 using namespace std;
  6 int root, n, m, Time = 0;
  7 int ch[MaxN][2], sz[MaxN], use[MaxN], R[MaxN], Max[MaxN], p[MaxN];
  8 char s[20];
  9 
 10 void push_up(int x){
 11     sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + use[x];
 12     Max[x] = max(Max[ch[x][0]], Max[ch[x][1]]);
 13     if (!use[x]) {
 14         Max[x] = max(Max[x], R[x]-x+1);
 15     }
 16 }
 17 
 18 void rotate(int x){
 19     int y = p[x], z = p[y];
 20     if (z) ch[z][ch[z][1] == y] = x;
 21     int l = ch[y][1] == x, r = l^1;
 22     p[x] = z;
 23     p[y] = x;
 24     p[ch[x][r]]    = y;
 25     
 26     ch[y][l] = ch[x][r];
 27     ch[x][r] = y;
 28     push_up(y);
 29     push_up(x);
 30 }
 31 
 32 void splay(int x, int fa){
 33     while (p[x] != fa){
 34         int y = p[x], z = p[y];
 35         if (z != fa){
 36             if ((ch[y][0]==x) ^ (ch[z][0]==y)) rotate(x);
 37             else rotate(y);
 38         }
 39         rotate(x);
 40     }
 41     if (!fa) root = x;
 42 }
 43 
 44 void Get(int k){
 45     int x = root;
 46     while (1) {
 47         if (sz[ch[x][0]] >= k) x = ch[x][0];
 48         else if (sz[ch[x][0]]+1 == k && use[x]) break;
 49         else k -= sz[ch[x][0]]+use[x], x = ch[x][1];
 50     }
 51     splay(x, 0);
 52 }
 53 
 54 void Reset(){
 55     root = 1;
 56     Max[1] = R[1] = n;
 57     ch[1][0] = ch[1][1] = use[1] = p[1] = sz[1] = 0;
 58 }
 59 
 60 int New(int k){
 61     int x = root;
 62     while (1){
 63         if (Max[ch[x][0]] >= k) x = ch[x][0];
 64         else if (!use[x] && R[x]-x+1 >= k) break;
 65         else x = ch[x][1];
 66     }
 67     splay(x, 0);
 68     use[x] = 1;
 69     if (k+x-1 < R[x]) {
 70         int to = k+x;
 71         ch[to][0] = 0, ch[to][1] = ch[x][1], p[ch[x][1]] = to;
 72         ch[x][1] = to, p[to] = x, use[to] = 0, R[to] = R[x];
 73         push_up(to);
 74         R[x] = to-1;
 75     }    
 76     push_up(x);
 77     return x;
 78 }
 79 
 80 void find(int k, int fa){
 81     int x = root;
 82     while (1){
 83         if (k < x) x = ch[x][0];
 84         else if (k > R[x]) x = ch[x][1];
 85         else break;
 86     }
 87     splay(x, fa);
 88 }
 89 
 90 void Free(int k){
 91     find(k, 0);
 92     if (!use[root]) { printf("Reject Free
"); return; }
 93     printf("Free from %d to %d
", root, R[root]);
 94     if (root > 1){
 95         find(root-1, root);
 96         if (!use[ch[root][0]]) root = ch[root][0], R[root] = R[p[root]], ch[root][1] = ch[p[root]][1], p[ch[root][1]] = root;
 97     }
 98     if (R[root] < n){
 99         find(R[root]+1, root);
100         if (!use[ch[root][1]]) R[root] = R[ch[root][1]], ch[root][1] = ch[ch[root][1]][1], p[ch[root][1]] = root;
101     }
102     use[root] = 0; p[root] = 0;
103     push_up(root);
104 }
105 
106 void print(int x){
107     if(!x) return;
108     print(ch[x][0]);
109     printf("from%d to%d ifuse%d Max%d
", x, R[x], use[x], Max[x]);
110     print(ch[x][1]);
111 }
112 
113 int main(){   
114     while (~scanf("%d%d", &n, &m)) {
115         Reset();
116         for (int i = 1, k; i <= m; i++){
117             scanf("%s", s);
118             if (s[0] != 'R') scanf("%d", &k);
119             if (s[0] == 'N'){
120                 if (Max[root] < k) printf("Reject New
");
121                 else printf("New at %d
", New(k));
122             }
123             else if (s[0] == 'F'){ Free(k); }
124             else if (s[0] == 'G'){
125                 if (sz[root] < k) printf("Reject Get
");
126                 else Get(k), printf("Get at %d
", root);
127             }  
128             else Reset(), printf("Reset Now
");
129 //            print(root);
130         }
131         printf("
");
132     }
133     return 0;
134 }
原文地址:https://www.cnblogs.com/Lukaluka/p/5081794.html