嗯 贴下代码 方便以后来看
treap : tyvj 普通平衡树
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<string> 7 8 using namespace std; 9 10 void setIO(const string& a) { 11 freopen((a+".in").c_str(), "r", stdin); 12 freopen((a+".out").c_str(), "w", stdout); 13 } 14 15 const int N = 200000 + 10; 16 17 struct Node{ 18 int v, r, sz; 19 Node* ch[2]; 20 Node(int v = 0) :v(v) { 21 r = rand(); 22 sz = 1; 23 ch[0] = ch[1] = 0; 24 } 25 26 void maintain() { 27 sz = 1; 28 if(ch[0]) sz += ch[0]->sz; 29 if(ch[1]) sz += ch[1]->sz; 30 } 31 32 int cmp(int x) const { 33 if(x == v) return -1; 34 return x < v ? 0 : 1; 35 } 36 }pool[N], *pis = pool, *root = NULL; 37 38 void rotate(Node*& o, int d) { 39 Node* t = o->ch[d]; 40 o->ch[d] = t->ch[d^1]; 41 t->ch[d^1] = o; 42 o->maintain(); 43 (o = t)->maintain(); 44 } 45 46 void insert(Node*& o, int x) { 47 if(!o) o = new(pis++) Node(x); 48 else { 49 int d = o->cmp(x); 50 if(d == -1) d = 0; 51 insert(o->ch[d], x); 52 o->maintain(); 53 if(o->ch[d]->r < o->r) rotate(o, d); 54 } 55 } 56 57 void remove(Node*& o, int x) { 58 if(!o) return; 59 int d = o->cmp(x); 60 if(d == -1) { 61 if(!o->ch[0]) o = o->ch[1]; 62 else if(!o->ch[1]) o = o->ch[0]; 63 else { 64 int d2 = o->ch[0]->r < o->ch[1]->r ? 0 : 1; 65 rotate(o, d2); 66 remove(o->ch[d2^1], x); 67 } 68 }else remove(o->ch[d], x); 69 if(o) o->maintain(); 70 } 71 72 int kth(Node* o, int k) { 73 int sz = (o->ch[0] ? o->ch[0]->sz : 0) + 1; 74 if(sz == k) return o->v; 75 if(sz < k) return kth(o->ch[1], k - sz); 76 else return kth(o->ch[0], k); 77 } 78 79 int rank(int x) { 80 int res = 0; 81 Node* o = root; 82 for(int d; o; o = o->ch[d]) { 83 d = o->cmp(x); 84 int sz = (o->ch[0] ? o->ch[0]->sz : 0) + 1; 85 if(o->v < x) res += sz; 86 if(d == -1) d = 0; 87 } 88 return res + 1; 89 } 90 91 int Pre(int x) { 92 int res = -1; 93 Node* o = root; 94 for(int d; o; o = o->ch[d]) { 95 d = o->cmp(x); 96 if(o->v < x) res = o->v; 97 if(d == -1) d = 0; 98 } 99 return res; 100 } 101 102 int Suf(int x) { 103 int res = -1; 104 Node*o = root; 105 for(int d; o; o = o->ch[d]) { 106 d = o->cmp(x); 107 if(o->v > x) res = o->v; 108 if(d == -1) d = 1; 109 } 110 return res; 111 } 112 113 int main() { 114 #ifdef DEBUG 115 freopen("in.txt", "r", stdin); 116 freopen("out.txt", "w", stdout); 117 #endif 118 119 int m,opt,x; 120 for(scanf("%d",&m);m--;){ 121 scanf("%d%d",&opt,&x); 122 if(opt==1) insert(root,x); 123 if(opt==2) remove(root,x); 124 if(opt==3) printf("%d\n",rank(x)); 125 if(opt==4) printf("%d\n",kth(root, x)); 126 if(opt==5) printf("%d\n",Pre(x)); 127 if(opt==6) printf("%d\n",Suf(x)); 128 } 129 130 return 0; 131 }
splay :tvvj文艺平衡术
自顶向下,不保留父亲版本
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<string> 7 8 using namespace std; 9 10 void setIO(const string& a) { 11 freopen((a+".in").c_str(), "r", stdin); 12 freopen((a+".out").c_str(), "w", stdout); 13 } 14 15 const int N = 200000 + 10; 16 struct Node* null; 17 18 struct Node { 19 int sz, v; 20 Node* ch[2]; 21 bool flip; 22 int cmp(int k) const { 23 int s = ch[0]->sz + 1; 24 if(k == s) return -1; 25 return k < s ? 0 : 1; 26 } 27 28 void down() { 29 if(!flip) return; 30 flip = 0; 31 swap(ch[0], ch[1]); 32 ch[0]->flip ^= 1; 33 ch[1]->flip ^= 1; 34 } 35 36 Node(int v = 0) : v(v) { 37 sz = 0; 38 ch[0] = ch[1] = null; 39 flip = 0; 40 } 41 42 void maintain() { 43 sz = ch[0]->sz + ch[1]->sz + 1; 44 } 45 }pool[N], *pis = pool, *root; 46 47 void init() { 48 null = new(pis++) Node(0); 49 null->ch[0] = null->ch[1] = null; 50 root = null; 51 } 52 53 int cnt = 0; 54 55 void build(Node*&o, int l, int r) { 56 if(l > r) return; 57 int mid = (l + r) >> 1; 58 o = new(pis++) Node(); 59 build(o->ch[0], l, mid - 1); 60 o->v = cnt++; 61 build(o->ch[1], mid + 1, r); 62 o->maintain(); 63 } 64 65 void rotate(Node*&o, int d) { 66 Node* t = o->ch[d]; 67 o->ch[d] = t->ch[d^1]; 68 t->ch[d^1] = o; 69 o->maintain(); 70 (o = t)->maintain(); 71 } 72 73 void splay(Node*& o, int k) { 74 o->down(); 75 int d = o->cmp(k); 76 if(d == -1) return; 77 if(d == 1) k -= o->ch[0]->sz + 1; 78 Node*& c = o->ch[d]; 79 c->down(); 80 int d2 = c->cmp(k); 81 if(d2 != -1) { 82 if(d2 == 1) k -= c->ch[0]->sz + 1; 83 splay(c->ch[d2], k); 84 if(d == d2) rotate(o, d); 85 else rotate(c, d2); 86 } 87 rotate(o, d); 88 } 89 90 void split(Node* o, int k, Node*& l, Node*& r) { 91 splay(o, k); 92 l = o; 93 r = o->ch[1]; 94 o->ch[1] = null; 95 o->maintain(); 96 } 97 98 Node* merge(Node* l, Node* r) { 99 splay(l, l->sz); 100 l->ch[1] = r; 101 l->maintain(); 102 return l; 103 } 104 105 void print(Node* o) { 106 if(o == null) return; 107 o->down(); 108 print(o->ch[0]); 109 if(o->v) printf("%d ", o->v); 110 print(o->ch[1]); 111 } 112 113 int main() { 114 #ifdef DEBUG 115 freopen("in.txt", "r", stdin); 116 freopen("out.txt", "w", stdout); 117 #endif 118 119 init(); 120 int n, m; 121 scanf("%d%d", &n, &m); 122 build(root, 0, n); 123 for(int i = 1; i <= m; i++) { 124 int l, r; 125 scanf("%d%d", &l, &r); 126 Node *o, *left, *mid, *right; 127 split(root, l, left, o); 128 split(o, r - l + 1, mid, right); 129 mid->flip ^= 1; 130 root = merge(merge(left, mid), right); 131 } 132 print(root); 133 134 return 0; 135 }
自底向上,保留父亲版本
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<string> 7 8 using namespace std; 9 10 void setIO(const string& a) { 11 freopen((a+".in").c_str(), "r", stdin); 12 freopen((a+".out").c_str(), "w", stdout); 13 } 14 15 const int N = 100000 + 10; 16 17 int n, m; 18 int ch[N][2], p[N], sz[N], root; 19 bool flip[N]; 20 21 #define l ch[x][0] 22 #define r ch[x][1] 23 24 void update(int x) { 25 if(x) sz[x] = sz[l] + sz[r] + 1; 26 } 27 28 void down(int x) { 29 if(flip[x]) { 30 swap(l, r); 31 flip[l] ^= 1; 32 flip[r] ^= 1; 33 flip[x] = 0; 34 } 35 } 36 37 #undef l 38 #undef r 39 40 bool isroot(int x) { 41 return p[x] != 0; 42 } 43 44 void rotate(int x) { 45 int y = p[x], z = p[y]; 46 /*if(!isroot(y)) 不用判断么*/ 47 if(z) ch[z][ch[z][1] == y] = x; 48 int l = ch[y][1] == x, r = l ^ 1; 49 50 p[x] = z; 51 p[y] = x; 52 p[ch[x][r]] = y; 53 54 ch[y][l] = ch[x][r]; 55 ch[x][r] = y; 56 57 update(y); 58 update(x); 59 } 60 61 void splay(int x, int FA) { 62 static int stk[N], top; 63 top = 0; 64 for(int t = x; t; t = p[t]) stk[++top] = t; 65 while(top) down(stk[top--]); 66 while(p[x] != FA) { 67 int y = p[x], z = p[y]; 68 if(z != FA) { 69 if((ch[y][1] == x) ^ (ch[z][1] == y)) rotate(y); 70 else rotate(x); 71 } 72 rotate(x); 73 } 74 if(!FA) root = x; 75 } 76 77 int cnt = 0; 78 79 int build(int sz) { 80 if(!sz) return 0; 81 int l = build(sz >> 1); 82 int x = ++cnt; 83 ch[x][0] = l; 84 int r = build(sz - (sz >> 1) - 1); 85 ch[x][1] = r; 86 87 if(l) p[l] = x; 88 if(r) p[r] = x; 89 90 update(x); 91 return x; 92 } 93 94 int kth(int k) { 95 for(int x = root; x;) { 96 down(x); 97 int s = sz[ch[x][0]] + 1; 98 if(s == k) return x; 99 if(s < k) k -= s, x = ch[x][1]; 100 else x = ch[x][0]; 101 } 102 return -1; 103 } 104 105 void rever(int l, int r) { 106 int x = kth(l), y = kth(r + 2); 107 splay(x, 0); 108 splay(y, x); 109 flip[ch[y][0]] ^= 1; 110 } 111 112 void print(int x) { 113 if(!x) return; 114 down(x); 115 print(ch[x][0]); 116 if(0 < x - 1 && x - 1 <= n) printf("%d ", x - 1); 117 print(ch[x][1]); 118 } 119 120 int main() { 121 #ifdef DEBUG 122 freopen("in.txt", "r", stdin); 123 freopen("out.txt", "w", stdout); 124 #endif 125 126 scanf("%d%d", &n, &m); 127 root = build(n + 2); 128 for(int i = 1; i <= m; i++) { 129 int l, r; 130 scanf("%d%d", &l, &r); 131 rever(l, r); 132 } 133 print(root); 134 135 return 0; 136 }
写惯了lct反而觉得保留父亲的好写一些...而且功能强大
lct
bzoj2157
修改单点只用splay(x), modify(x), update(x)即可,发现以前竟然还要newroot(x), access(x)不知道在干什么。
改一条链要先newroot(x), access(y), splay(y);
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<string> 7 8 using namespace std; 9 10 void setIO(const string& a) { 11 freopen((a+".in").c_str(), "r", stdin); 12 freopen((a+".out").c_str(), "w", stdout); 13 } 14 15 const int N = 20000 * 2 + 10; 16 17 int n, m; 18 int ch[N][2], p[N], sz[N], mn[N], mx[N], sum[N], w[N]; 19 bool flip[N], rev[N]; 20 21 bool isroot(int x) { 22 return ch[p[x]][0] != x && ch[p[x]][1] != x; 23 } 24 25 #define l ch[x][0] 26 #define r ch[x][1] 27 28 void rever(int x) { 29 sum[x] *= -1; 30 w[x] *= -1; 31 swap(mn[x], mx[x]); 32 mn[x] *= -1; 33 mx[x] *= -1; 34 rev[x] ^= 1; 35 } 36 37 void update(int x) { 38 if(!x) return; 39 sum[x] = w[x] + sum[l] + sum[r]; 40 mn[x] = min(mn[l], mn[r]); 41 mx[x] = max(mx[l], mx[r]); 42 if(x > n) mn[x] = min(mn[x], w[x]), mx[x] = max(mx[x], w[x]); 43 sz[x] = sz[l] + sz[r] + 1; 44 } 45 46 void down(int x) { 47 if(!x) return; 48 if(flip[x]) { 49 swap(l, r); 50 flip[l] ^= 1; 51 flip[r] ^= 1; 52 flip[x] ^= 1; 53 } 54 if(rev[x]) { 55 rev[x] = 0; 56 if(l) rever(l); 57 if(r) rever(r); 58 } 59 } 60 61 #undef l 62 #undef r 63 64 void rotate(int x) { 65 int y = p[x], z = p[y]; 66 int l = ch[y][1] == x, r = l ^ 1; 67 if(!isroot(y)) ch[z][ch[z][1] == y] = x; 68 p[y] = x; 69 p[x] = z; 70 p[ch[x][r]] = y; 71 72 ch[y][l] = ch[x][r]; 73 ch[x][r] = y; 74 75 update(y); 76 update(x); 77 } 78 79 void splay(int x) { 80 static int stk[N], top; 81 stk[top = 1] = x; 82 for(int t = x; !isroot(t); t = p[t]) stk[++top] = p[t]; 83 while(top) down(stk[top--]); 84 85 while(!isroot(x)) { 86 int y = p[x], z = p[y]; 87 if(!isroot(y)) { 88 if((ch[y][1] == x) ^ (ch[z][1] == y)) rotate(x); else rotate(y); 89 } 90 rotate(x); 91 } 92 } 93 94 void access(int x) { 95 for(int t = 0; x; x = p[t = x]) { 96 splay(x); 97 ch[x][1] = t; 98 update(x); 99 } 100 } 101 102 void newroot(int x) { 103 access(x); 104 splay(x); 105 flip[x] ^= 1; 106 } 107 108 void Link(int x, int y) { 109 newroot(x); 110 p[x] = y; 111 } 112 113 const int INF = int(1e9); 114 115 void init() { 116 scanf("%d", &n); 117 int u, v, ww; 118 for(int i = 0; i <= n; i++) { 119 mn[i] = INF, mx[i] = -INF; 120 } 121 for(int i = 1; i < n; i++) { 122 scanf("%d%d%d", &u, &v, &ww); ++u, ++v; 123 w[i + n] = ww; 124 Link(u, i + n); 125 Link(v, i + n); 126 } 127 } 128 129 void n_as(int x, int y) { 130 newroot(x); 131 access(y); 132 splay(y); 133 } 134 135 void work() { 136 char opt[100]; 137 int x, y; 138 for(scanf("%d", &m); m--; ) { 139 scanf("%s%d%d", opt, &x, &y); 140 if(opt[0] == ‘C‘) { 141 int o = x + n; 142 splay(o); 143 w[o] = y; 144 update(o); 145 }else { 146 ++x, ++y; 147 n_as(x, y); 148 if(opt[0] == ‘N‘) rever(y); 149 else if(opt[0] == ‘S‘) printf("%d\n", sum[y]); 150 else { 151 if(opt[1] == ‘I‘) printf("%d\n", mn[y]); 152 else printf("%d\n", mx[y]); 153 } 154 } 155 } 156 } 157 158 int main() { 159 #ifdef DEBUG 160 freopen("in.txt", "r", stdin); 161 freopen("out.txt", "w", stdout); 162 #endif 163 164 init(); 165 work(); 166 167 return 0; 168 }
链剖
bzoj1036
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<string> 7 8 using namespace std; 9 10 void setIO(const string& a) { 11 freopen((a+".in").c_str(), "r", stdin); 12 freopen((a+".out").c_str(), "w", stdout); 13 } 14 15 const int N = 30000 + 10, M = 30000 + 10, INF = ~0u>>1; 16 17 int n; 18 19 struct Data{ 20 int s, m; 21 Data(int s = 0, int m = -INF) : s(s), m(m) {} 22 Data operator + (const Data& rhs) const { 23 return Data(s + rhs.s, max(m, rhs.m)); 24 } 25 }; 26 27 struct SegmentTree{ 28 Data da[N * 4]; 29 int lft, rgt, w; 30 31 #define mid ((l + r) >> 1) 32 #define ls s << 1, l, mid 33 #define rs s << 1 | 1, mid + 1, r 34 35 void modify(int s, int l, int r) { 36 if(l == r) { 37 da[s] = Data(w, w); 38 return; 39 } 40 if(lft <= mid) modify(ls); 41 else modify(rs); 42 da[s] = da[s << 1] + da[s << 1 | 1]; 43 } 44 45 Data query(int s, int l, int r) { 46 if(lft <= l && r <= rgt) return da[s]; 47 if(rgt <= mid) return query(ls); 48 if(mid < lft) return query(rs); 49 return query(ls) + query(rs); 50 } 51 52 void Modify(int p, int w) { 53 lft = p, this->w = w; 54 modify(1, 1, n); 55 } 56 57 Data Query(int l, int r) { 58 lft = l, rgt = r; 59 return query(1, 1, n); 60 } 61 }seg; 62 63 struct Edge{ 64 int to; 65 Edge* next; 66 Edge(int to = 0, Edge* next = 0) :to(to), next(next) {} 67 }pool[M * 2], *pis = pool, *fir[N]; 68 69 void AddEdge(int u, int v) { 70 fir[u] = new(pis++) Edge(v, fir[u]); 71 fir[v] = new(pis++) Edge(u, fir[v]); 72 } 73 74 int sz[N], fa[N], son[N], dep[N]; 75 76 void dfs(int u) { 77 sz[u] = 1; 78 son[u] = 0; 79 for(Edge* p = fir[u]; p; p = p->next) { 80 int v = p->to; 81 if(v == fa[u]) continue; 82 fa[v] = u; 83 dep[v] = dep[u] + 1; 84 dfs(v); 85 sz[u] += sz[v]; 86 if(sz[v] > sz[son[u]]) son[u] = v; 87 } 88 } 89 90 int pos[N], top[N], dfs_clk; 91 92 void build(int u, int pre) { 93 top[u] = pre; 94 pos[u] = ++dfs_clk; 95 if(son[u]) build(son[u], pre); 96 for(Edge* p = fir[u]; p; p = p->next) { 97 int v = p->to; 98 if(v == fa[u] || v == son[u]) continue; 99 build(v, v); 100 } 101 } 102 103 Data query(int a, int b) { 104 int ta = top[a], tb = top[b]; 105 Data res; 106 for(; ta != tb; a = fa[ta], ta = top[a]) { 107 if(dep[tb] > dep[ta]) swap(a, b), swap(ta, tb); 108 res = res + seg.Query(pos[ta], pos[a]); 109 } 110 if(dep[b] < dep[a]) swap(a, b); 111 return res + seg.Query(pos[a], pos[b]); 112 } 113 114 int main() { 115 #ifdef DEBUG 116 freopen("in.txt", "r", stdin); 117 freopen("out.txt", "w", stdout); 118 #endif 119 120 scanf("%d", &n); 121 for(int i = 1; i < n; i++) { 122 int u, v; 123 scanf("%d%d", &u, &v); 124 AddEdge(u, v); 125 } 126 127 dfs(1); 128 build(1, 1); 129 130 for(int w, i = 1; i <= n; i++) { 131 scanf("%d", &w); 132 seg.Modify(pos[i], w); 133 } 134 135 int m, a, b; 136 scanf("%d", &m); 137 char cmd[10]; 138 139 while(m--) { 140 scanf("%s%d%d", cmd, &a, &b); 141 if(cmd[0] == ‘C‘) seg.Modify(pos[a], b); 142 else if(cmd[1] == ‘S‘) printf("%d\n", query(a, b).s); 143 else printf("%d\n", query(a, b).m); 144 } 145 146 return 0; 147 }
以前线段树的接口有点蛋疼,现在改了一下。
没有写蛋疼的合并区间。。
还有之前的stl非动态内存heap
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<string> 7 8 using namespace std; 9 10 void setIO(const string& a) { 11 freopen((a+".in").c_str(), "r", stdin); 12 freopen((a+".out").c_str(), "w", stdout); 13 } 14 15 const int N = 1000000 + 10; 16 17 int a[N]; 18 19 struct Heap { 20 int da[N], sz; 21 void push(const int& x) { 22 da[sz++] = x; 23 push_heap(da, da+sz); 24 } 25 int top() const { 26 return da[0]; 27 } 28 void pop() { 29 pop_heap(da, da + (sz--)); 30 } 31 void init() { 32 make_heap(da, da+sz); 33 } 34 }q; 35 36 #include<ctime> 37 #include<queue> 38 priority_queue<int> Q; 39 40 int main() { 41 #ifdef DEBUG 42 freopen("in.txt", "r", stdin); 43 freopen("out.txt", "w", stdout); 44 #endif 45 46 int n; 47 scanf("%d", &n); 48 for(int i = 0; i < n; i++) { 49 scanf("%d", a + i); 50 } 51 52 int t1 = clock(); 53 54 for(int i = 0; i < n; i++) { 55 Q.push(a[i]); 56 } 57 58 while(Q.size()) { 59 // printf("%d ", Q.top()); 60 Q.pop(); 61 } 62 63 cout << endl; 64 cout << (t1 = clock() - t1) << endl; 65 66 for(int i = 0; i < n; i++) { 67 q.push(a[i]); 68 } 69 70 while(q.sz) { 71 // printf("%d ", q.top()); 72 q.pop(); 73 } 74 75 cout<< endl; 76 cout << clock() - t1 << endl; 77 78 return 0; 79 }
时间: 2024-09-28 19:05:46