HDU1890 Robotic Sort
来源:互联网 发布:linux vim命令详解 编辑:程序博客网 时间:2024/06/04 18:10
我不是code的生产者,我只是code的搬运工。(感谢cxlove世界冠军提供参考代码,我已经成功从中提取了模板= =)
好吧,其实这个除了上一题的模板之外完全是我自己写的,连那个remove函数都是现编的= =
要注意的是数据可能有重复,需要处理一下。
splay中使用rotate函数,用时296MS:
#include <cstdio>#include <cstring>#include <cmath>#include <iostream>#include <vector>#include <set>#include <queue>#include <stack>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 100010;int n;int val[maxn], fa[maxn], ch[maxn][2], size[maxn], root, tot;int rev[maxn];struct node{ int v, id; bool operator < (const node &o) const { return (v==o.v && id < o.id) || v < o.v; }}a[maxn];inline void init(){ root = tot = 0; val[0] = fa[0] = ch[0][0] = ch[0][1] = size[0] = 0; rev[0] = 0;}inline void newnode(int x, int value, int father){ val[x] = value; fa[x] = father; ch[x][0] = ch[x][1] = 0; size[x] = 1; rev[x] = 0;}inline void push_down(int x){ if (!rev[x]) return; swap(ch[x][0], ch[x][1]); rev[ch[x][0]] ^= 1; rev[ch[x][1]] ^= 1; rev[x] = 0;}inline void push_up(int x){ size[x] = size[ch[x][0]] + size[ch[x][1]] + 1;}inline void rotate(int x, int kind){ int y = fa[x]; push_down(x); push_down(y); ch[y][kind^1] = ch[x][kind]; fa[ch[x][kind]] = y; if (fa[y]) ch[fa[y]][ch[fa[y]][1]==y] = x; fa[x] = fa[y]; ch[x][kind] = y; fa[y] = x; push_up(y);}inline void splay(int x, int goal){ push_down(x); while (fa[x] != goal) { int y = fa[x]; if (fa[y] == goal) { push_down(y); push_down(x); rotate(x, ch[y][0]==x); } else { push_down(fa[y]); push_down(y); push_down(x); int kind = ch[fa[y]][0]==y; if (ch[y][kind] == x) {rotate(x, kind^1); rotate(x, kind);} else {rotate(y, kind); rotate(x, kind);} } } push_up(x); if (goal == 0) root = x;}inline void remove(int x){ int y = fa[x]; if (!ch[x][0]) { ch[y][ch[y][1]==x] = ch[x][1]; fa[ch[x][1]] = y; } else { int z = ch[x][0]; push_down(z); while (ch[z][1]) { z = ch[z][1]; push_down(z); } splay(z, y); ch[z][1] = ch[x][1]; fa[ch[x][1]] = z; ch[y][ch[y][1]==x] = z; fa[z] = y; }}inline void build(int &x, int l, int r, int father){ if (l > r) return; int mid = (l + r) >> 1; newnode(x = mid, a[mid].v, father); if (l < mid) build(ch[x][0], l, mid-1, x); if (mid < r) build(ch[x][1], mid+1, r, x); push_up(x);}int main(){ while (scanf("%d", &n) == 1 && n) { for (int i=1;i<=n;i++) scanf("%d", &a[i].v), a[i].id = i; sort(a+1, a+n+1); init(); build(root, 1, n, 0); for (int i=1;i<n;i++) { int x = a[i].id; splay(x, 0); printf("%d ", size[ch[x][0]] + i); rev[ch[x][0]] ^= 1; remove(root); } printf("%d\n", n); } return 0;}
splay中使用zigzag,用时281MS:
#include <cstdio>#include <cstring>#include <cmath>#include <iostream>#include <vector>#include <set>#include <queue>#include <stack>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 100010;int n;int val[maxn], fa[maxn], ch[maxn][2], size[maxn], root, tot;int rev[maxn];struct node{ int v, id; bool operator < (const node &o) const { return (v==o.v && id < o.id) || v < o.v; }}a[maxn];inline void init(){ root = tot = 0; val[0] = fa[0] = ch[0][0] = ch[0][1] = size[0] = 0; rev[0] = 0;}inline void newnode(int x, int value, int father){ val[x] = value; fa[x] = father; ch[x][0] = ch[x][1] = 0; size[x] = 1; rev[x] = 0;}inline void push_down(int x){ if (!rev[x]) return; swap(ch[x][0], ch[x][1]); rev[ch[x][0]] ^= 1; rev[ch[x][1]] ^= 1; rev[x] = 0;}inline void push_up(int x){ size[x] = size[ch[x][0]] + size[ch[x][1]] + 1;}inline void zig(int x){ int y = fa[x], z = fa[y]; ch[y][1] = ch[x][0]; fa[ch[x][0]] = y; ch[x][0] = y; fa[y] = x; fa[x] = z; if (z) ch[z][ch[z][1]==y] = x; push_up(y);}inline void zag(int x){ int y = fa[x], z = fa[y]; ch[y][0] = ch[x][1]; fa[ch[x][1]] = y; ch[x][1] = y; fa[y] = x; fa[x] = z; if (z) ch[z][ch[z][1]==y] = x; push_up(y);}inline void zigzig(int x){ int y = fa[x], z = fa[y], fz = fa[z]; ch[z][1] = ch[y][0]; fa[ch[y][0]] = z; ch[y][1] = ch[x][0]; fa[ch[x][0]] = y; fa[z] = y; ch[y][0] = z; fa[y] = x; ch[x][0] = y; fa[x] = fz; if (fz) ch[fz][ch[fz][1]==z] = x; push_up(z); push_up(y);}inline void zagzag(int x){ int y = fa[x], z = fa[y], fz = fa[z]; ch[z][0] = ch[y][1]; fa[ch[y][1]] = z; ch[y][0] = ch[x][1]; fa[ch[x][1]] = y; fa[z] = y; ch[y][1] = z; fa[y] = x; ch[x][1] = y; fa[x] = fz; if (fz) ch[fz][ch[fz][1]==z] = x; push_up(z); push_up(y);}inline void zigzag(int x){ int y = fa[x], z = fa[y], fz = fa[z]; ch[y][1] = ch[x][0]; fa[ch[x][0]] = y; ch[z][0] = ch[x][1]; fa[ch[x][1]] = z; fa[y] = fa[z] = x; ch[x][0] = y; ch[x][1] = z; fa[x] = fz; if (fz) ch[fz][ch[fz][1]==z] = x; push_up(z); push_up(y);}inline void zagzig(int x){ int y = fa[x], z = fa[y], fz = fa[z]; ch[y][0] = ch[x][1]; fa[ch[x][1]] = y; ch[z][1] = ch[x][0]; fa[ch[x][0]] = z; fa[y] = fa[z] = x; ch[x][1] = y; ch[x][0] = z; fa[x] = fz; if (fz) ch[fz][ch[fz][1]==z] = x; push_up(z); push_up(y);}void splay(int x, int goal){ int y, z; push_down(x); while(fa[x] != goal) { int y = fa[x]; if (fa[y] == goal){ push_down(y); push_down(x); if (ch[y][1] == x) zig(x); else zag(x); } else { z = fa[y]; push_down(z); push_down(y); push_down(x); if (ch[z][1] == y) { if (ch[y][1] == x) zigzig(x); else zagzig(x); } else { if (ch[y][0] == x) zagzag(x); else zigzag(x); } } } push_up(x); if (fa[x] == 0) root=x;}inline void remove(int x){ int y = fa[x]; if (!ch[x][0]) { ch[y][ch[y][1]==x] = ch[x][1]; fa[ch[x][1]] = y; } else { int z = ch[x][0]; push_down(z); while (ch[z][1]) { z = ch[z][1]; push_down(z); } splay(z, y); ch[z][1] = ch[x][1]; fa[ch[x][1]] = z; ch[y][ch[y][1]==x] = z; fa[z] = y; }}inline void build(int &x, int l, int r, int father){ if (l > r) return; int mid = (l + r) >> 1; newnode(x = mid, a[mid].v, father); if (l < mid) build(ch[x][0], l, mid-1, x); if (mid < r) build(ch[x][1], mid+1, r, x); push_up(x);}int main(){ while (scanf("%d", &n) == 1 && n) { for (int i=1;i<=n;i++) scanf("%d", &a[i].v), a[i].id = i; sort(a+1, a+n+1); init(); build(root, 1, n, 0); for (int i=1;i<n;i++) { int x = a[i].id; splay(x, 0); printf("%d ", size[ch[x][0]] + i); rev[ch[x][0]] ^= 1; remove(root); } printf("%d\n", n); } return 0;}
所以说,虽然提速不是太多,但是zigzag也算是一个外挂吧,关键时刻说不定会有用。
- HDU1890 Robotic Sort
- hdu1890 Robotic Sort(Splay)
- Splay hdu1890 Robotic Sort
- HDU1890 Robotic Sort(Splay)
- 伸展树 - hdu1890 Robotic Sort
- [hdu1890 Robotic Sort]Splay Tree
- hdu1890 Robotic Sort splay+懒惰标记+翻转
- HDU1890 Robotic Sort(slpay,区间旋转)
- hdu1890 Robotic Sort Splay树,区间反转,lazy标记
- Robotic Sort hdu1890 (伸展树翻转+删根)
- hdu1890 Robotic Sort (splay+区间翻转单点更新)
- hdu 1089 Robotic Sort
- hdoj 1890 Robotic Sort
- HDU Robotic Sort
- HDOJ 1890 Robotic Sort
- HDU 1890 Robotic Sort
- HDU 1890 Robotic Sort
- hdu 1890 Robotic Sort
- 我的四轴专用PID参数整定方法及原理---超长文慎入
- [转]开发者们大量编程带来的快乐和烦恼
- ubuntu下设置开机自启动项
- linux XXX.tar.xz file
- 去除ArcMap中Catalog窗口中的失效文件夹连接
- HDU1890 Robotic Sort
- 代码健壮性的几点思考
- 全面理解Unity加载和内存管理机制之二:进一步深入和细节
- POJ 3006 Dirichlet's Theorem on Arithmetic Progressions ( 素数、筛选)
- 全面理解Unity加载和内存管理之一
- WHU 2013 Summer Team Contest #16 - 2008 beijing[xioumu]
- Unity3D占用内存太大怎么解决呢?
- linux ipc
- 由浅入深探究mysql索引结构原理、性能分析与优化