zoukankan      html  css  js  c++  java
  • [LuoguP3391] 文艺平衡树

    题目背景

     

    题目描述

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列。

    其中需要提供以下操作:翻转一个区间,例如原有序序列是 5 4 3 2 15 4 3 2 1,翻转区间是 [2,4][2,4] 的话,结果是 5 2 3 4 15 2 3 4 1。

    输入格式

    第一行两个正整数 n,mn,m,表示序列长度与操作个数。序列中第 ii 项初始为 ii。
    接下来 mm 行,每行两个正整数 l,rl,r,表示翻转的区间。

    输出格式

    输出一行 nn 个正整数,表示原始序列经过 mm 次变换后的结果。

    输入输出样例

    输入 #1
    5 3
    1 3
    1 3
    1 4
    输出 #1
    4 3 2 1 5

    说明/提示

    【数据范围】
    对于 100\%100% 的数据,1 le n, m leq 1000001n,m100000,1 le l le r le n1lrn。

     
    以前是用的splay
    这次用的fhq treap 好写太多了
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1000000 + 10;
    struct Tree{
        int val, size, lc, rc, pri;
        bool tag;
        Tree(){
            size = 0;
        }
        Tree(int val): val(val){
            size = 1;
            lc = rc = 0;
            tag = false;
            pri = rand();
        }
    }t[maxn];
    int root = 0, tcnt = 0;
    inline void pushdown(int x){
        if(t[x].tag){
            swap(t[x].lc, t[x].rc);
            t[t[x].lc].tag ^= 1;
            t[t[x].rc].tag ^= 1;
            t[x].tag = false;
        }
    }
    inline void pushup(int x){
        t[x].size = t[t[x].lc].size + t[t[x].rc].size + 1;
    }
    void split(int x, int &a, int &b, int k){
        if(!x){
            a = b = 0;
            return;
        }
        pushdown(x);
        if(k <= t[t[x].lc].size){
            b = x;
            split(t[x].lc, a, t[b].lc, k);
        }
        else{
            a = x;
            split(t[x].rc, t[a].rc, b, k - t[t[x].lc].size - 1);
        }
        pushup(x);
    }
    inline int newnode(int val){
        t[++tcnt] = Tree(val);
        return tcnt;
    }
    void merge(int &x, int a, int b){
        if(!a || !b){
            x = a | b;
            return;
        }
        pushdown(a); pushdown(b);
        if(t[a].pri < t[b].pri){
            x = a;
            merge(t[x].rc, t[a].rc, b);
        }
        else{
            x = b;
            merge(t[x].lc, a, t[b].lc);
        }
        pushup(x);
    }
    void bl(int x){
        if(!x) return;
        pushdown(x);
        bl(t[x].lc);
        cout << t[x].val << ' ';
        bl(t[x].rc);
    }
    int main(){
        int n, m;
        cin >> n >> m;
        for(int i = 1; i <= n; i++){
            merge(root, root, newnode(i));
        }
        int l, r, a, b, c;
        for(int i = 1; i <= m; i++){
            cin >> l >> r;
            split(root, a, b, l - 1);
            split(b, b, c, r - l + 1);
            t[b].tag = 1;
            merge(b, a, b);
            merge(root, b, c);
        }
        bl(root); putchar('
    ');
        return 0;
    }
  • 相关阅读:
    1029: [JSOI2007]建筑抢修
    1028: [JSOI2007]麻将
    1050 棋盘染色 2
    1026: [SCOI2009]windy数
    1074: [SCOI2007]折纸origami
    839. Optimal Marks
    1024: [SCOI2009]生日快乐
    1025: [SCOI2009]游戏
    1023: [SHOI2008]cactus仙人掌图
    对前面的总结
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/12107654.html
Copyright © 2011-2022 走看看