HDU - 2871 Memory Control (Splay)
题意:
要求实现一个内存控制器:
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\n"); return; } 93 printf("Free from %d to %d\n", 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\n", 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\n"); 121 else printf("New at %d\n", 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\n"); 126 else Get(k), printf("Get at %d\n", root); 127 } 128 else Reset(), printf("Reset Now\n"); 129 // print(root); 130 } 131 printf("\n"); 132 } 133 return 0; 134 }