zoukankan      html  css  js  c++  java
  • codevs 1743 反转卡片

      题意

        有一个长度为n的序列,序列为n的一个排列。每次找到序列的第一个数k,若k=1则退出,否则区间[1,k]进行翻转,直至k=1或翻转次数大于100000。n<=300000

      这题是Splay翻转裸题,但是,我调了一个晚上,毕竟很久没有打过Splay。

      问题是出在一开始构建Splay的过程之中,没有建最大最小的点,而我是用数组写的,第0位设为空,在翻转的过程中,很容易就跑到第0位去了,然后无限TLE,一定要吸取教训啊。

    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    
    using namespace std;
    
    #define ls(x) (ch[x][0])
    #define rs(x) (ch[x][1])
    const int maxn = 300005;
    int n, a[maxn];
    struct Tree
    {
        int ch[maxn][2], siz[maxn], rev[maxn], fa[maxn], val[maxn], cnt, root;
        Tree()
        {
            root = cnt = 0;
        }
        void new_node(int &x, int c)
        {
            x = ++cnt;
            ch[x][0] = ch[x][1] = fa[x] = rev[x] = 0;
            siz[x] = 1;
            val[x] = c;
        }
        void pushup(int x)
        {
            siz[x] = siz[ls(x)]+siz[rs(x)]+1;
        }
        void pushdown(int x)
        {
            if (rev[x] == 0)
                return ;
            swap(ls(x), rs(x));
            rev[ls(x)] ^= rev[x], rev[rs(x)] ^= rev[x];
            rev[x] = 0;
        }
        void build(int &x, int l, int r, int f)
        {
            if (l > r)
                return ;
            int mid = (l+r)>>1;
            new_node(x, a[mid]);
            build(ls(x), l, mid-1, x);
            build(rs(x), mid+1, r, x);
            fa[x] = f;
            pushup(x);
        }
        void rotate(int x, int f)
        {
            int y = fa[x];
            pushdown(x);
            fa[ch[x][!f]] = y;
            ch[y][f] = ch[x][!f];
            fa[x] = fa[y];
            if (fa[y])
                ch[fa[y]][ls(fa[y]) == y ? 0 : 1] = x;
            ch[x][!f] = y;
            fa[y] = x;
            pushup(y);
        }
        void splay(int x, int goal)
        {
            pushdown(x);
            while (fa[x] != goal)
            {
                int y = fa[x], z = fa[y];
                if (z == goal)
                {
                    rotate(x, ls(y) == x ? 0 : 1);
                    break ;
                }
                int f = ls(z) == y ? 0 : 1;
                if (ch[y][f] == x)
                    rotate(y, f), rotate(x, f);
                else
                    rotate(x, !f), rotate(x, f);
            }
            pushup(x);
            if (goal == 0)
                root = x;
        }
        void rotateto(int k, int goal)
        {
            int x = root;
            pushdown(x);
            while (siz[ls(x)]+1 != k)
            {
                if (siz[ls(x)] >= k)
                    x = ls(x);
                else
                {
                    k -= siz[ls(x)]+1;
                    x = rs(x);
                }
                pushdown(x);
            }
            splay(x, goal);
        }
        void rever(int k)
        {
            rotateto(1, 0);
            rotateto(k+2, root);
            rev[ls(rs(root))] ^= 1;
        }
        int find(int k)
        {
            int x = root;
            pushdown(x);
            while (siz[ls(x)]+1 != k)
            {
                if (siz[ls(x)] >= k)
                    x = ls(x);
                else
                {
                    k -= siz[ls(x)]+1;
                    x = rs(x);
                }
                pushdown(x);
            }
            return val[x];
        }
    }T;
    
    int main()
    {
        scanf("%d", &n);
        for (int i = 2; i <= n+1; ++i)
            scanf("%d", &a[i]);
        T.build(T.root, 1, n+2, 0);
        int k = T.find(2), ans = 0;
        while (k != 1)
        {
            T.rever(k);
            ans ++;
            if (ans > 100000)
            {
                ans = -1;
                break ;
            }
            k = T.find(2);
        }
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    算法的时间复杂度与空间复杂度
    递归八皇后问题(回溯算法)
    vue之插件
    递归之打印、阶乘、九九乘法表、迷宫问题
    选择排序
    归并排序
    sql 字符保留汉字处理
    JAVA filter map groupingBy Collectors
    2021最新版IDEA激活
    WPF 程序退出,进程依然存在
  • 原文地址:https://www.cnblogs.com/-ZZB-/p/6407811.html
Copyright © 2011-2022 走看看