zoukankan      html  css  js  c++  java
  • 2018牛客多校第三场 C.Shuffle Cards

    题意:

      给出一段序列,每次将从第p个数开始的s个数移到最前面。求最终的序列是什么。

    题解:

      Splay翻转模板题。存下板子。

    #include <bits/stdc++.h>
    using namespace std;
    const int INF = 1e6;
    const int N = 1e5+10;
    int n, m;
    int s, t;
    int root, sz, tot;
    int key[N], f[N], size[N], delta[N], cnt[N], ch[N][2];
    int a[N], ans[N];
    int get(int x) {
        return ch[f[x]][1] == x;
    }
    void update(int x) {
        if(x) {
            size[x] = cnt[x];
            if(ch[x][0]) size[x] += size[ch[x][0]];
            if(ch[x][1]) size[x] += size[ch[x][1]];
        }
    }
    int build(int l, int r, int fa) {
        if (l > r) return 0;
        int mid = l+r>>1;
        int now = ++sz;
        key[now] = a[mid]; f[now] = fa; cnt[now] = 1;
        int lch = build(l, mid-1, now);
        int rch = build(mid+1, r, now);
        ch[now][0] = lch, ch[now][1] = rch;
        update(now);
        return now;
    }
    void pushdown(int x) {
        if(x && delta[x]) {
            swap(ch[x][0], ch[x][1]);
            delta[ch[x][0]] ^= 1; delta[ch[x][1]] ^= 1;
            delta[x] = 0;
        }
    }
    void rotate(int x) {
        pushdown(f[x]);
        pushdown(x);
        int old = f[x], oldf = f[old], which = get(x);
        ch[old][which] = ch[x][which^1]; f[ch[old][which]] = old;
        f[old] = x; ch[x][which^1] = old;
        f[x] = oldf;
        if(oldf) ch[oldf][ch[oldf][1]==old] = x;
        update(old); update(x);
    }
    void splay(int x, int tar) {
        for(int fa; (fa = f[x])!=tar; rotate(x))
            if(f[fa] != tar)
                rotate((get(x)==get(fa))?fa:x);
        if(!tar) root = x;
    }
    int find(int x) {
        int now = root, fa = 0;
        while(1) {
            pushdown(now);
            if(x <= size[ch[now][0]])
                now = ch[now][0];
            else {
                x -= size[ch[now][0]]+1;
                if(x == 0) return now;
                now = ch[now][1];
            }
        }
    }
    void print(int now) {
        pushdown(now);
        if(ch[now][0]) print(ch[now][0]);
        if(key[now]!=-INF && key[now]!=INF) ans[++tot] = key[now];
        if(ch[now][1]) print(ch[now][1]);
    }
    int main() {
        scanf("%d%d", &n, &m);
        a[1] = -INF; a[n+2] = INF;
        for(int i = 2; i <= n+1; i++) a[i] = i-1;
        root = build(1, n+2, 0);
        while(m--) {
            scanf("%d%d", &s, &t);
            if(s == 1) continue;
            int f1 = find(1);
            int f2 = find(s+t+1);
            splay(f1, 0);
            splay(f2, f1);
            delta[ch[ch[root][1]][0]] ^= 1;
            f2 = find(t+2);
            splay(f2, f1);
            delta[ch[ch[root][1]][0]] ^= 1;
            f1 = find(t+1);
            f2 = find(s+t+1);
            splay(f1, 0);
            splay(f2, f1);
            delta[ch[ch[root][1]][0]]^=1;
        }
        print(root);
        for(int i = 1; i < n; i++) printf("%d ", ans[i]);
        printf("%d
    ", ans[n]);
    }
    View Code
  • 相关阅读:
    leetcode刷题-131~
    leetcode刷题-106~114/116~122/125/127/129~130
    leetcode刷题-100~105
    Intel-Pin的windows安装
    九、appium自动化框架综合实践
    QQ传文件用例设计
    mysql常用语句
    谐云试用的日子
    码农开发资料集
    MyBatis中一个SQL语句的执行过程解析
  • 原文地址:https://www.cnblogs.com/Pneuis/p/9380771.html
Copyright © 2011-2022 走看看