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也算是一个外挂吧,关键时刻说不定会有用。

原创粉丝点击