poj 3580 SuperMemo(Splay)

来源:互联网 发布:java date json 编辑:程序博客网 时间:2024/05/05 11:59

               基本包括了Splay Tree的所有操作,插入,删除,右移,翻转,区间更新,区间查询。学习Splay Tree推荐一个博客,FZU_Jason。这道题基本上就是抄的他的。。

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#define LL long long#define CLR(a, b) memset(a, b, memset(a))using namespace std;const int N = 200010;const int INF = 0x7FFFFFFF;struct SplayTree{    int size, root, top;    int st[N], a[N];    int ch[N][2], pre[N], key[N], num[N];    //num 当前根下节点个数    int add[N], mini[N];    bool flip[N];    inline void PushUp(int x)    {        num[x] = num[ch[x][0]] + num[ch[x][1]] + 1;        mini[x] = min(mini[ch[x][0]], mini[ch[x][1]]);        mini[x] = min(mini[x], key[x]);    }    inline void PushDown(int x)    {        int L, R;        L = ch[x][0];R = ch[x][1];        if(add[x])        {            if(L)            {                add[L] += add[x];                key[L] += add[x];                mini[L] += add[x];            }            if(R)            {                add[R] += add[x];                key[R] += add[x];                mini[R] += add[x];            }            add[x] = 0;        }        if(flip[x])        {            flip[L] ^= true;            flip[R] ^= true;            swap(ch[x][0], ch[x][1]);            flip[x] = false;        }    }    void NewNode(int &x, int father, int val)    {        if(top != -1)            x = st[top --];        else            x = ++size;        ch[x][0] = ch[x][1] = add[x] = 0;        pre[x] = father;        key[x] = mini[x] = val;        num[x] = 1;        flip[x] = false;    }    void Build(int &x, int L, int R, int father)    {        if(L <= R)        {            int mid = (L + R) >> 1;            NewNode(x, father, a[mid]);            Build(ch[x][0], L, mid - 1, x);            Build(ch[x][1], mid + 1, R, x);            PushUp(x);        }    }    void Init(int n)    {        root = size = 0;        top = -1;        flip[0] = false;        ch[0][0] = ch[0][1] = pre[0] = num[0] = add[0] = 0;        key[0] = mini[0] = INF;        NewNode(root, 0, INF);        NewNode(ch[root][1], root, INF);        Build(ch[ch[root][1]][0], 1, n, ch[root][1]);        PushUp(ch[root][1]);        PushUp(root);    }    void Rotate(int x, int kind)    {        int y = pre[x];        PushDown(x);        ch[y][!kind] = ch[x][kind];        pre[ch[x][kind]] = y;        if(pre[y])            ch[pre[y]][ch[pre[y]][1] == y] = x;        pre[x] = pre[y];        ch[x][kind] = y;        pre[y] = x;        PushUp(y);    }    void Splay(int r, int goal)    {        while(pre[r] != goal)        {            if(pre[pre[r]] == goal) Rotate(r, ch[pre[r]][0] == r);            else            {                int y = pre[r];                int kind = ch[pre[y]][0] == y;                if(ch[y][kind] == r)                    Rotate(r, !kind), Rotate(r, kind);                else                    Rotate(y, kind), Rotate(r, kind);            }        }        //PushUp(r);        if(goal == 0) root = r;    }    /*    void Rotate(int x, int kind) {        int y, z;        y = pre[x];        z = pre[y];        PushDown(y);        ch[y][!kind] = ch[x][kind];        pre[ch[x][kind]] = y;        ch[z][ch[z][1] == y] = x;        pre[x] = z;        ch[x][kind] = y;        pre[y] = x;        PushUp(y);    }    void Splay(int x, int goal) {        if (x != goal) {            PushDown(x);            while (pre[x] != goal) {                if (ch[pre[x]][0] == x)                    Rotate(x, 1);                else                    Rotate(x, 0);            }            PushUp(x);            if (!goal)                root = x;        }    }    */    int Select(int k)    {        int x;        PushDown(root);        for(x = root; num[ch[x][0]] + 1 != k;)        {            if(num[ch[x][0]] + 1 > k)                x = ch[x][0];            else                k -= num[ch[x][0]] + 1, x = ch[x][1];            PushDown(x);        }        return x;    }    void Add(int x, int y, int val)    {        int t;        x = Select(x - 1);        y = Select(y + 1);        Splay(x, 0);        Splay(y, x);        t = ch[y][0];        add[t] += val;        key[t] += val;        mini[t] += val;        PushUp(y);        PushUp(x);    }    void Flip(int x, int y)    {        x = Select(x - 1);        y = Select(y + 1);        Splay(x, 0);        Splay(y, x);        flip[ch[y][0]] ^= true;    }    void Revolve(int x, int y, int t)    {        int cnt = y - x + 1;        t %= cnt;        if(t < 0)            t += cnt;        if(t)        {            Flip(x, y - t);            Flip(y - t + 1, y);            Flip(x, y);        }    }    void Insert(int x, int val)    {        int a, b;        a = Select(x);        b = Select(x + 1);        Splay(a, 0);        Splay(b, a);        NewNode(ch[b][0], b, val);        PushUp(b);        PushUp(a);    }    void Delete(int x)    {        int a, b;        a = Select(x - 1);        b = Select(x + 1);        Splay(a, 0);        Splay(b, a);        st[++ top] = ch[b][0];        ch[b][0] = 0;        PushUp(b);        PushUp(a);    }    int MIN(int x, int y)    {        x = Select(x - 1);        y = Select(y + 1);        Splay(x, 0);        Splay(y, x);        return mini[ch[y][0]];    }}spt;int main() {    char cmd[18];    int n, q, i;    int x, y, val;    while (~scanf("%d", &n)) {        for (i = 1; i <= n; i++)            scanf("%d", &spt.a[i]);        spt.Init(n);        scanf("%d", &q);        while (q--) {            scanf(" %s", cmd);            if (strcmp(cmd, "ADD") == 0) {                scanf("%d%d%d", &x, &y, &val);                spt.Add(x + 1, y + 1, val);            } else if (strcmp(cmd, "REVERSE") == 0) {                scanf("%d%d", &x, &y);                spt.Flip(x + 1, y + 1);            } else if (strcmp(cmd, "REVOLVE") == 0) {                scanf("%d%d%d", &x, &y, &val);                spt.Revolve(x + 1, y + 1, val);            } else if (strcmp(cmd, "INSERT") == 0) {                scanf("%d%d", &x, &val);                spt.Insert(x + 1, val);            } else if (strcmp(cmd, "DELETE") == 0) {                scanf("%d", &x);                spt.Delete(x + 1);            } else {                scanf("%d%d", &x, &y);                printf("%d\n", spt.MIN(x + 1, y + 1));            }        }    }    return 0;}


0 0
原创粉丝点击