zoukankan      html  css  js  c++  java
  • Shuffle Cards ( Gym

    题目

      https://vjudge.net/problem/Gym-247729C

    题意

      给出 n,m 表示初始序列 1 ~ n 以及 m 个操作,每个操作是将 p 位置开始之后的 s 个数放至最前面。

    题解

      题意十分简单,可是做不粗来,蒟蒻的我。首先可以想到,将一段区间 [ l,  r ] 放至最前方可以通过翻转 [ 1, l - 1 ] , [ l, r ] , [ 1, r ] 三个步骤得到,这样就转化成了 splay 的经典用法。这也是第一次学到splay。

    #include <bits/stdc++.h>
    // #include <iostream>
    // #include <cstring>
    // #include <string>
    // #include <algorithm>
    // #include <cmath>
    // #include <cstdio>
    // #include <queue>
    // #include <stack>
    // #include <map>
    // #include <bitset>
    // #include <set>
    // #include <vector>
    // #include <iomanip>
    #define ll long long
    #define ull unsigned long long
    #define met(a, b) memset(a, b, sizeof(a))
    #define rep(i, a, b) for(int i = a; i <= b; ++i)
    #define bep(i, a, b) for(int i = a; i >= b; --i)
    #define lowbit(x) (x&(-x))
    #define MID (l + r) / 2
    #define ls pos*2
    #define rs pos*2+1
    #define pb push_back
    #define ios() ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
    
    using namespace std;
    
    const int maxn = 1e6 + 1010;
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const ll mod = 1e9 + 7;
    const double eps = 1e-4;
    const double PI = acos(-1);
    
    struct Splay_tree {
        int val, fa, sub_size, now_size, tag;
        int son[2];
    }tree[maxn];
    
    int root;
    int arr[maxn];
    int cnt;
    int if_;
    
    void push_down(int x) {
        if(x && tree[x].tag) {
            tree[tree[x].son[0]].tag ^= 1;
            tree[tree[x].son[1]].tag ^= 1;
            tree[x].tag = 0;
            swap(tree[x].son[0], tree[x].son[1]);
        }
    }
    void update(int x) {
        if(x) {
            tree[x].sub_size = tree[x].now_size;
            tree[x].sub_size += tree[tree[x].son[0]].sub_size;
            tree[x].sub_size += tree[tree[x].son[1]].sub_size;
        }
    }
    int build_tree(int l, int r, int fa) {
        if(l > r) return 0;
        int mid = MID;
        int now = ++cnt;
        tree[now].val = arr[mid];
        tree[now].fa = fa;
        tree[now].now_size = 1;
        tree[now].tag = 0;
        tree[now].son[0] = build_tree(l, mid - 1, now);
        tree[now].son[1] = build_tree(mid + 1, r, now);
        update(now);
        return now;
    }
    void rotate(int x) {
        int fx = tree[x].fa, ffx = tree[fx].fa;
        int k = (tree[fx].son[1] == x);
        push_down(fx);
        push_down(x);
        tree[fx].son[k] = tree[x].son[k ^ 1];
        tree[tree[fx].son[k]].fa = fx;
        tree[x].son[k ^ 1] = fx;
        tree[fx].fa = x;
        tree[x].fa = ffx;
        if(ffx) tree[ffx].son[tree[ffx].son[1] == fx] = x;
        update(fx);
        update(x);
    }
    void splay(int x, int goal) {
        while(tree[x].fa != goal) {
            int y = tree[x].fa, z = tree[y].fa;
            if(z != goal) {
                ((tree[z].son[1] == y) == (tree[y].son[1] == x)) ? rotate(y) : rotate(x);
            }
            rotate(x);
        }
        if(!goal) root = x;
    }
    int find(int x) {
        int now = root;
        while(1) {
            push_down(now);
            if(x <= tree[tree[now].son[0]].sub_size) {
                now = tree[now].son[0];
            }
            else {
                x -= tree[tree[now].son[0]].sub_size + 1;
                if(!x) return now;
                now = tree[now].son[1];
            }
        }
    }
    void Reverse(int x, int y) {
        int l = find(x - 1);
        int r = find(y + 1);
        splay(l, 0);
        splay(r, l);
        int pos = tree[r].son[0];
        tree[pos].tag ^= 1;
    }
    void dfs(int x) {
        push_down(x);
        if(tree[x].son[0]) dfs(tree[x].son[0]);
        if(tree[x].val != inf && tree[x].val != -inf) {
            if(if_) cout << ' ';
            else if_ = 1;
            cout << tree[x].val;
        }
        if(tree[x].son[1]) dfs(tree[x].son[1]);
    }
    
    int main() {
        int n, m;
        cin >> n >> m;
        rep(i, 2, n + 1) arr[i] = i - 1;
        arr[1] = -inf;
        arr[n + 2] = inf;
        //前后加入数据是为了防止 reverse(1, n) 这种边界时 find 出错。
        root = build_tree(1, n + 2, 0);
        rep(i, 1, m) {
            int pos, len;
            cin >> pos >> len;
            int l = pos + 1, r = l + len - 1;
            Reverse(l, r);
            Reverse(2, l - 1);
            Reverse(2, r);
        }
        dfs(root);
        return 0;
    }
  • 相关阅读:
    Leetcode 191.位1的个数 By Python
    反向传播的推导
    Leetcode 268.缺失数字 By Python
    Leetcode 326.3的幂 By Python
    Leetcode 28.实现strStr() By Python
    Leetcode 7.反转整数 By Python
    Leetcode 125.验证回文串 By Python
    Leetcode 1.两数之和 By Python
    Hdoj 1008.Elevator 题解
    TZOJ 车辆拥挤相互往里走
  • 原文地址:https://www.cnblogs.com/Ruby-Z/p/12894087.html
Copyright © 2011-2022 走看看