日历
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
28 | 29 | 30 | 31 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
统计
- 随笔 - 20
- 文章 - 1
- 评论 - 40
- 引用 - 0
导航
常用链接
留言簿(3)
随笔档案
文章档案
搜索
最新评论

阅读排行榜
评论排行榜
|
很久以前有且写过一次splay。。。然后被它要记父亲的旋转囧到。。然后从此就再也没写过。。 这几天刚省选完没事做,就准备再写一下。 在sqybi神牛的文章的指导下很快又回忆起了splay的操作。。 于是从头开始YY一个splay。。。总体感觉比treap要难写。。(Treap性价比真的很高),但要比treap强大许多。。。 感觉上splay完全可以代替线段树了。。只是常数太大了。。 做了两道splay的题: 序列终结者 http://61.187.179.132:8080/JudgeOnline/showproblem?problem_id=1251 CERC2007 sort:http://contest.felk.cvut.cz/07cerc/solved.html sort这题标程比我多用了一个优化:因为已经排好序的数就没用了,所以可以从树里面删去,从而使整棵树不断变小,越来越快。相比我没用的程序要快了1倍。。 - -! 感觉splay越来越亲切了~确实太强大了。。 还有就是我觉得我的splay写复杂了。。每次写完都要调各种囧问题。。 求神牛们splay优美漂亮的写法!。orz
codes: 序列终结者
1 #include <iostream> 2 3 #define MAXN 50010 4 #define INFINITE 1000000000000000000ll 5 #define MAX(a,b) ((a) > (b) ? (a) : (b)) 6 #define ll long long 7 8 using namespace std; 9 10 class Node { 11 public: 12 int lt, rt, rev, size, fa; 13 ll v, t, max; 14 inline void swap() { 15 int tmp = lt; lt = rt; rt = tmp; 16 rev ^= 1; 17 } 18 inline void Add(ll _v) { 19 v += _v, t += _v, max += _v; 20 } 21 }; 22 Node node[MAXN+1]; 23 int cntNode = 0; 24 class SplayTree { 25 private: 26 int root; 27 void Down(int x) { 28 int lc = node[x].lt, rc = node[x].rt, t; 29 if (node[x].rev) { 30 node[lc].swap(), node[rc].swap(); 31 node[x].rev = 0; 32 } 33 if (t = node[x].t) { 34 node[lc].Add(t), node[rc].Add(t); 35 node[x].t = 0; 36 } 37 } 38 void Renew(int x) { 39 int lc = node[x].lt, rc = node[x].rt; 40 node[x].max = MAX(node[lc].max, node[rc].max); 41 node[x].max = MAX(node[x].max, node[x].v); 42 node[x].size = node[lc].size + node[rc].size + 1; 43 } 44 int Find(int x, int k) { 45 int lc = node[x].lt; 46 if (k == node[lc].size + 1) return x; 47 Down(x); 48 if (k <= node[lc].size) return Find(lc, k); 49 return Find(node[x].rt, k - node[lc].size - 1); 50 } 51 void RightRotate(int x) { 52 int lc = node[x].lt, fa = node[x].fa; 53 Down(x); Down(lc); 54 node[x].lt = node[lc].rt; node[node[x].lt].fa = x; 55 node[lc].rt = x; node[x].fa = lc; 56 node[lc].fa = fa; 57 if (fa) { 58 if (x == node[fa].lt) 59 node[fa].lt = lc; 60 else 61 node[fa].rt = lc; 62 } 63 Renew(x); 64 Renew(lc); 65 } 66 void LeftRotate(int x) { 67 int rc = node[x].rt, fa = node[x].fa; 68 Down(x); Down(rc); 69 node[x].rt = node[rc].lt; node[node[x].rt].fa = x; 70 node[rc].lt = x; node[x].fa = rc; 71 node[rc].fa = fa; 72 if (fa) { 73 if (x == node[fa].lt) 74 node[fa].lt = rc; 75 else 76 node[fa].rt = rc; 77 } 78 Renew(x); 79 Renew(rc); 80 } 81 void Splay(int x, int FA = 0) { 82 int fa, Fa; 83 while ((fa = node[x].fa) != FA) { 84 if ((Fa = node[fa].fa) == FA) { 85 if (x == node[fa].lt) 86 RightRotate(fa); 87 else 88 LeftRotate(fa); 89 }else { 90 if (x == node[fa].lt) { 91 if (fa == node[Fa].lt) { 92 RightRotate(Fa); 93 RightRotate(fa); 94 }else { 95 RightRotate(fa); 96 LeftRotate(Fa); 97 } 98 }else { 99 if (fa == node[Fa].rt) { 100 LeftRotate(Fa); 101 LeftRotate(fa); 102 }else { 103 LeftRotate(fa); 104 RightRotate(Fa); 105 } 106 } 107 } 108 } 109 if (FA == 0) 110 root = x; 111 } 112 void print(int x) { 113 if (node[x].lt) fprintf(stderr,"%d lt: %d\n",x,node[x].lt), print(node[x].lt); 114 if (node[x].rt) fprintf(stderr,"%d rt: %d\n",x,node[x].rt), print(node[x].rt); 115 } 116 public: 117 SplayTree():root(0) {} 118 void SetRoot(int _root) { 119 root = _root; 120 } 121 int BuildTree(int l, int r, int fa) { 122 if (l>r) return 0; 123 int x = ++cntNode; 124 int mid = (l + r) >> 1; 125 node[x].size = r - l + 1; 126 node[x].fa = fa; 127 node[x].lt = BuildTree(l, mid-1, x); 128 node[x].rt = BuildTree(mid+1,r, x); 129 return x; 130 } 131 void Reverse(int l, int r) { 132 Splay(l = Find(l-1), 0); 133 Splay(r = Find(r+1), l); 134 node[node[r].lt].swap(); 135 } 136 void Add(int l, int r, ll v) { 137 Splay(l = Find(l-1), 0); 138 Splay(r = Find(r+1), l); 139 node[node[r].lt].Add(v); 140 } 141 ll AskMax(int l, int r) { 142 Splay(l = Find(l-1), 0); 143 Splay(r = Find(r+1), l); 144 return node[node[r].lt].max; 145 } 146 int Find(int k) { 147 return Find(root, k); 148 } 149 void print() { 150 print(root); 151 for (int i = 1; i<=cntNode; i++) 152 fprintf(stderr, "%d ", node[i].max); 153 fprintf(stderr, "\n"); 154 } 155 }T; 156 #define BUFSIZE 100000*100 157 char buf[BUFSIZE+1], *pt = buf; 158 ll Sign; 159 //void scan_int(int &t) 160 #define scan_int(t) \ 161  { \ 162 t = 0; \ 163 while ((!((*pt) >= '0' && (*pt) <= '9')) && (*pt)!='-') pt++; \ 164 if ((*(pt)) == '-') Sign = -1, pt++; else Sign = 1; \ 165 while (((*pt) >= '0' && (*pt) <= '9')) t = t * 10ll + (*(pt++)) - '0'; \ 166 t *= Sign; \ 167 } 168 169 /**//* 170 void scan_int(ll &t) 171 { 172 t = 0; 173 while ((!((*pt) >= '0' && (*pt) <= '9')) && (*pt)!='-') pt++; 174 if ((*(pt)) == '-') Sign = -1, pt++; else Sign = 1; 175 while (((*pt) >= '0' && (*pt) <= '9')) t = t * 10ll + (*(pt++)) - '0'; 176 t *= Sign; 177 } 178 */ 179 int main() 180  { 181 int n,m; 182 scanf("%d%d",&n,&m); 183 T.SetRoot(T.BuildTree(0, n+1, 0)); 184 #ifdef DEBUG 185 T.print(); 186 #endif 187 node[0].max = -INFINITE; 188 int cmd, l, r; 189 ll v; 190 fread(buf, 1, BUFSIZE, stdin); 191 while (m--) { 192 //scanf("%d%d%d",&cmd,&l,&r); 193 scan_int(cmd); scan_int(l); scan_int(r); 194 l++, r++; 195 if (cmd == 1) { 196 //scanf("%I64d",&v); 197 scan_int(v); 198 T.Add(l, r, v); 199 }else if (cmd == 2) 200 T.Reverse(l, r); 201 else if (cmd == 3) 202 printf("%I64d\n", T.AskMax(l, r)); 203 #ifdef DEBUG 204 T.print(); 205 #endif 206 } 207 return 0; 208 } 209 210
sort:
1 #include <iostream> 2 #define MAXN 100010 3 #define INFINITE 1000000000 4 #define MIN(a,b) ((a) < (b) ? (a) : (b)) 5 6 using namespace std; 7 8 class Stuff { 9 public: 10 int id,v; 11 }; 12 class SplayNode { 13 public: 14 int lt, rt, fa, size, v, rev, min; 15 void Reverse() { 16 rev ^= 1; 17 int tmp = lt; lt = rt; rt = tmp; 18 } 19 }; 20 SplayNode node[MAXN+1]; 21 int cntNode = 0; 22 class SplayTree { 23 private: 24 int root; 25 void Renew(int x) { 26 int lc = node[x].lt, rc = node[x].rt; 27 node[x].min = MIN(node[lc].min, node[rc].min); 28 node[x].min = MIN(node[x].min, node[x].v); 29 node[x].size = node[lc].size + node[rc].size + 1; 30 } 31 void Down(int x) { 32 if (node[x].rev) { 33 node[node[x].lt].Reverse(); node[node[x].rt].Reverse(); 34 node[x].rev = 0; 35 } 36 } 37 int FindMinPos(int x, int v) { 38 if (node[x].v == v) return node[node[x].lt].size + 1; 39 Down(x); 40 if (node[node[x].lt].min == v) return FindMinPos(node[x].lt, v); 41 return node[node[x].lt].size + 1 + FindMinPos(node[x].rt, v); 42 } 43 int FindKthID(int x, int k) { 44 if (k == node[node[x].lt].size + 1) return x; 45 Down(x); 46 if (k <= node[node[x].lt].size) return FindKthID(node[x].lt, k); 47 return FindKthID(node[x].rt, k - node[node[x].lt].size - 1); 48 } 49 void RightRotate(int x) { 50 int lc = node[x].lt, fa = node[x].fa; 51 Down(x); Down(lc); 52 node[x].lt = node[lc].rt; node[node[x].lt].fa = x; 53 node[lc].rt = x; node[x].fa = lc; 54 node[lc].fa = fa; 55 if (fa) { 56 if (x == node[fa].lt) node[fa].lt = lc; 57 else node[fa].rt = lc; 58 } 59 Renew(x); Renew(lc); 60 } 61 void LeftRotate(int x) { 62 int rc = node[x].rt, fa = node[x].fa; 63 Down(x); Down(rc); 64 node[x].rt = node[rc].lt; node[node[x].rt].fa = x; 65 node[rc].lt = x; node[x].fa = rc; 66 node[rc].fa = fa; 67 if (fa) { 68 if (x == node[fa].lt) node[fa].lt = rc; 69 else node[fa].rt = rc; 70 } 71 Renew(x); Renew(rc); 72 } 73 void Splay(int x, int FA = 0) { 74 int fa, Fa; 75 while ((fa = node[x].fa) != FA) { 76 if ((Fa = node[fa].fa) == FA) { 77 if (x == node[fa].lt) 78 RightRotate(fa); 79 else 80 LeftRotate(fa); 81 }else { 82 if (x == node[fa].lt) { 83 if (fa == node[Fa].lt) 84 RightRotate(Fa), RightRotate(fa); 85 else 86 RightRotate(fa), LeftRotate(Fa); 87 }else { 88 if (fa == node[Fa].rt) 89 LeftRotate(Fa), LeftRotate(fa); 90 else 91 LeftRotate(fa), RightRotate(Fa); 92 } 93 } 94 } 95 if (FA == 0) root = x; 96 } 97 void Print(int x) { 98 int t; 99 if (t = node[x].lt) fprintf(stderr, "%d lt: %d\n", x, t), Print(t); 100 if (t = node[x].rt) fprintf(stderr, "%d rt: %d\n", x, t), Print(t); 101 } 102 public: 103 void Reset() { 104 node[0].min = INFINITE; 105 cntNode = 0; 106 } 107 void SetRoot(int _root) { 108 root = _root; 109 } 110 int FindKthID(int k) { 111 return FindKthID(root, k); 112 } 113 int BuildTree(int l, int r, int *a, int fa = 0) { 114 if (l > r) return 0; 115 int x = ++cntNode; 116 int mid = (l + r) >> 1; 117 node[x].fa = fa, node[x].v = a[mid], node[x].size = 1; 118 node[x].rev = 0; 119 node[x].lt = BuildTree(l, mid - 1, a, x); 120 node[x].rt = BuildTree(mid + 1, r, a, x); 121 Renew(x); 122 return x; 123 } 124 int AskMinPos(int l, int r) { 125 l = FindKthID(l - 1); 126 Splay(l, 0); 127 r = FindKthID(r + 1); 128 Splay(r, l); 129 return node[node[l].lt].size + 1 + FindMinPos(node[r].lt, node[node[r].lt].min); 130 } 131 void Reverse(int l, int r) { 132 if (l == r) return; 133 Splay(l = FindKthID(l - 1), 0); 134 Splay(r = FindKthID(r + 1), l); 135 node[node[r].lt].Reverse(); 136 } 137 int Print() { 138 Print(root); 139 fprintf(stderr, "\n"); 140 return 0; 141 } 142 }; 143 144 Stuff a[MAXN+1]; 145 SplayTree T; 146 int b[MAXN+1]; 147 int n; 148 bool Init() { 149 scanf("%d",&n); 150 if (!n) 151 return false; 152 for (int i = 1; i<=n; i++) 153 scanf("%d",&a[i].v), a[i].id = i; 154 } 155 156 157 int cmpStuff(const void *a, const void *b) { 158 Stuff _a = (*(Stuff *)a), _b = (*(Stuff *)b); 159 if (_a.v != _b.v) return _a.v - _b.v; 160 return _a.id - _b.id; 161 } 162 163 //#define DEBUG 164 void Solve() { 165 // Discretization 166 a[0].v = -INFINITE; 167 a[n+1].v = INFINITE, a[n+1].id = n+1; 168 qsort(a, n+2, sizeof(a[0]), cmpStuff); 169 for (int i = 0; i<=n+1; i++) 170 b[a[i].id] = i; 171 172 // Build Tree 173 // Make the initial tree balanced 174 T.Reset(); 175 T.SetRoot(T.BuildTree(0, n+1, b)); 176 #ifdef DEBUG 177 T.Print(); 178 #endif 179 // Work 180 int p; 181 for (int i = 1; i<=n; i++) { 182 printf("%d ", (p = T.AskMinPos(i+1, n+1)) - 1); 183 #ifdef DEBUG 184 fprintf(stderr, "%d ", p - 1); 185 #endif 186 T.Reverse(i+1, p); 187 } 188 printf("\n"); 189 #ifdef DEBUG 190 fprintf(stderr, "\n"); 191 #endif 192 } 193 194 int main() { 195 freopen("s.in","r",stdin); 196 freopen("s.out","w",stdout); 197 while (Init()) 198 Solve(); 199 return 0; 200 } 201
评论:
-
# re: 学习笔记-Splay[未登录]
Posted @ 2010-04-09 17:16
边坐沙发边膜拜。 回复 更多评论
-
# re: 学习笔记-Splay
Posted @ 2010-09-24 22:52
嗯?Tim神犇有splay的论文吗? 回复 更多评论
|