标签:
支持区间最小值查询,区间翻转的数据结构
直接上treap板子啊亲!没了。。。
只是为了存板用的2333
1 /************************************************************** 2 Problem: 1552 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:2456 ms 7 Memory:5572 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <algorithm> 12 13 using namespace std; 14 const int N = 1e5 + 5; 15 const int inf = 1e9; 16 17 inline int read(); 18 inline void print(int, char); 19 20 int n, a[N]; 21 22 namespace treap { 23 struct node; 24 node *null, *root; 25 26 struct node { 27 node *ls, *rs; 28 int sz, v; 29 bool rev; 30 int mn, wmn; 31 32 node() {} 33 node (int _v) : v(_v) { 34 ls = rs = null; 35 rev = 0, sz = 1; 36 mn = _v, wmn = -1; 37 } 38 39 #define Len (1 << 16) 40 void* operator new(size_t, int _v) { 41 static node *mempool, *c; 42 if (c == mempool) 43 mempool = (c = new node[Len]) + Len; 44 *c = node(_v); 45 return c++; 46 } 47 #undef Len 48 49 inline void push() { 50 if (rev) { 51 swap(ls, rs); 52 ls -> rev ^= 1, rs -> rev ^= 1; 53 if (wmn != -1) wmn ^= 1; 54 rev = 0; 55 } 56 } 57 inline void update() { 58 sz = ls -> sz + rs -> sz + 1; 59 wmn = -1, mn = v; 60 if (ls -> mn <= mn) wmn = 0, mn = ls -> mn; 61 if (rs -> mn < mn) wmn = 1, mn = rs -> mn; 62 } 63 }; 64 65 inline unsigned int rand() { 66 static unsigned int res = 2333; 67 return res += res << 2 | 1; 68 } 69 inline int random(int x, int y) { 70 return rand() % (x + y) < x; 71 } 72 73 void build(node *&p, int *a, int l, int r) { 74 if (l > r) return; 75 p = new(a[l + r >> 1])node; 76 if (l == r) return; 77 build(p -> ls, a, l, (l + r >> 1) - 1); 78 build(p -> rs, a, (l + r >> 1) + 1, r); 79 p -> update(); 80 } 81 82 void merge(node *&p, node *x, node *y) { 83 if (x == null || y == null) { 84 p = x == null ? y : x; 85 p -> update(); 86 return; 87 } 88 if (random(x -> sz, y -> sz)) { 89 x -> push(), p = x; 90 merge(p -> rs, x -> rs, y); 91 p -> update(); 92 } else { 93 y -> push(), p = y; 94 merge(p -> ls, x, y -> ls); 95 p -> update(); 96 } 97 } 98 99 void split(node *p, node *&x, node *&y, int k) { 100 if (!k) { 101 x = null, y = p; 102 return; 103 } 104 if (k == p -> sz) { 105 x = p, y = null; 106 return; 107 } 108 p -> push(); 109 if (p -> ls -> sz >= k) { 110 y = p; 111 split(p -> ls, x, y -> ls, k); 112 y -> update(); 113 } else { 114 x = p; 115 split(p -> rs, x -> rs, y, k - p -> ls -> sz - 1); 116 x -> update(); 117 } 118 } 119 120 inline void reverse(int l, int r) { 121 static node *x, *y, *z; 122 split(root, x, z, l - 1); 123 split(z, y, z, r - l + 1); 124 y -> rev ^= 1; 125 root = x; 126 merge(root, root, y); 127 merge(root, root, z); 128 } 129 130 inline int get_min(node *p) { 131 p -> push(); 132 if (p -> wmn == 0) return get_min(p -> ls); 133 if (p -> wmn == -1) return p -> ls -> sz + 1; 134 return p -> ls -> sz + 1 + get_min(p -> rs); 135 } 136 inline void modify(node *p, int k, int _v) { 137 p -> push(); 138 if (p -> ls -> sz + 1 == k) p -> v = _v; 139 else if (p -> ls -> sz >= k) modify(p -> ls, k, _v); 140 else modify(p -> rs, k - p -> ls -> sz - 1, _v); 141 p -> update(); 142 } 143 }; 144 145 int tmp[N], tmp2[N]; 146 inline bool cmp(int x, int y) { 147 return tmp[x] == tmp[y] ? x < y : tmp[x] < tmp[y]; 148 } 149 150 int main() { 151 int i, x; 152 using namespace treap; 153 n = read(); 154 for (i = 1; i <= n; ++i) tmp[i] = read(), tmp2[i] = i; 155 sort(tmp2 + 1, tmp2 + n + 1, cmp); 156 for (i = 1; i <= n; ++i) a[tmp2[i]] = i; 157 null = new(inf)node; 158 null -> ls = null -> rs = null, null -> sz = 0; 159 build(root, a, 1, n); 160 for (i = 1; i <= n; ++i) { 161 print(x = get_min(root), i == n ? ‘\n‘ : ‘ ‘); 162 reverse(i, x); 163 modify(root, i, inf); 164 } 165 return 0; 166 } 167 168 inline int read() { 169 static int x; 170 static char ch; 171 x = 0, ch = getchar(); 172 while (ch < ‘0‘ || ‘9‘ < ch) 173 ch = getchar(); 174 while (‘0‘ <= ch && ch <= ‘9‘) { 175 x = x * 10 + ch - ‘0‘; 176 ch = getchar(); 177 } 178 return x; 179 } 180 181 inline void print(int t, char ch = ‘ ‘) { 182 static int tot, pr[10]; 183 tot = 0; 184 while (t) 185 pr[++tot] = t % 10, t /= 10; 186 if (!tot) putchar(‘0‘); 187 while (tot) putchar(pr[tot--] + ‘0‘); 188 putchar(ch); 189 }
BZOJ1552 [Cerc2007]robotic sort
标签:
原文地址:http://www.cnblogs.com/rausen/p/4471202.html