[BZOJ3223][tyvj1729]文艺平衡树

3223: Tyvj 1729 文艺平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 5356  Solved: 3163 [Submit][Status][Discuss]

Description

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1

Input

第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n)  m表示翻转操作次数 接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n

Output

输出一行n个数字,表示原始序列经过m次变换后的结果

Sample Input

5 3

1 3

1 3

1 4

Sample Output

4 3 2 1 5

对区间维护splay,翻转打标记即可

#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 100000 + 10;
int n, m;
int root, fa[maxn], son[maxn][2], siz[maxn], val[maxn];
bool tag[maxn] = {false};
int num[maxn], cnt = 0;
inline void pushup(int x){
    siz[x] = siz[son[x][0]] + siz[son[x][1]] + 1;
}
inline void rotate(int x){
    int y = fa[x], p = son[y][0] == x;
    son[y][!p] = son[x][p];
    fa[son[x][p]] = y;
    fa[x] = fa[y];
    if(fa[x]) son[fa[x]][son[fa[x]][1] == y] = x;
    son[x][p] = y;
    fa[y] = x;
    pushup(y);
}
inline void splay(int x, int t){
    int y, z;
    while(fa[x] != t){
        if(fa[fa[x]] == t) rotate(x);
        else{
            y = fa[x];
            z = fa[y];
            if(son[y][0] == x ^ son[z][0] == y) rotate(x);
            else rotate(y);
            rotate(x);
        }
    }
    pushup(x);
    if(!t) root = x;
}
inline void pushdown(int x){
    if(tag[x]){
        swap(son[x][0], son[x][1]);
        tag[son[x][0]] ^= 1;
        tag[son[x][1]] ^= 1;
        tag[x] = 0;
    }
}
inline void find(int kth, int t){
    int x = root, tmp;
    while(x){
        pushdown(x);
        tmp = siz[son[x][0]];
        if(kth == tmp + 1){
            splay(x, t);
            return;
        }
        if(kth > tmp + 1){
            kth -= tmp + 1;
            x = son[x][1];
        }
        else x = son[x][0];
    }
}
int build(int l, int r){
    if(l > r) return 0;
    int now = ++cnt, mid = l + r >> 1;
    val[now] = num[mid];
    siz[now] = 1;
    son[now][0] = build(l, mid - 1);
    if(son[now][0]) fa[son[now][0]] = now;
    son[now][1] = build(mid + 1, r);
    if(son[now][1]) fa[son[now][1]] = now;
    pushup(now);
    return now;
}
void init(){
    scanf("%d %d", &n, &m);
    siz[0] = son[0][0] = son[0][1] = 0;
    num[1] = num[n + 2] = 66662333;
    for(int i = 1; i <= n; i++) num[i + 1] = i;
    root = build(1, n + 2);
}
void zx(int x){
    if(!x) return;
    pushdown(x);
    zx(son[x][0]);
    printf("%d ", val[x]);
    zx(son[x][1]);
}
void work(){
    for(int l, r, i = 1; i <= m; i++){
        scanf("%d %d", &l, &r);
        find(l, 0);
        find(r + 2, root);
        tag[son[son[root][1]][0]] ^= 1;
    }
    find(1, 0);
    find(n + 2, root);
    zx(son[son[root][1]][0]);
}
int main(){
    init();
    work();
    return 0;
}
时间: 2024-10-07 09:09:44

[BZOJ3223][tyvj1729]文艺平衡树的相关文章

[BZOJ3223] [Tyvj1729] 文艺平衡树 (splay)

Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 Input 第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n)  m表示翻转操作次数 接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n Output 输出一行n个数字,表示原始序列经过m次变换后的结果 Sample Input 5 3 1 3

[Bzoj3223][Tyvj1729] 文艺平衡树(splay/无旋Treap)

题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3223 平衡树处理区间问题的入门题目,普通平衡树那道题在维护平衡树上是以每个数的值作为维护的标准,而处理区间问题时,维护平衡树的应该是每个位置的下标,所以平衡树中序遍历时应该是当前区间的样子.例如: {1 2 3 4 5}翻转区间1 3,则中序遍历应该输出{3,2,1,4,5}. 提供splay和无旋Treap的做法. splay做法: 1 #include<bits/stdc++.h>

TYVJ1729文艺平衡树

传送门:http://tyvj.cn/Problem_Show.aspx?id=1729 文艺平衡树 From admin 背景 Background 此为平衡树系列第二道:文艺平衡树 描述 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 输入格式 InputFormat 第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……

【BZOJ3223】文艺平衡树(splay)

题意:维护数列的翻转 n<=100000 思路:裸splay,仅维护rever 1 var t:array[0..200000,0..1]of longint; 2 size,rev,b,fa,a:array[0..200000]of longint; 3 n,m,i,x,y,root:longint; 4 5 procedure pushup(p:longint); 6 begin 7 size[p]:=size[t[p,0]]+size[t[p,1]]+1; 8 end; 9 10 proc

【bzoj3223】文艺平衡树

#include<bits/stdc++.h> #define N 300005 #define rat 4 using namespace std; struct Node{ int size,val,rev; Node *lc,*rc; Node(int s,int v,Node *a,Node *b):size(s),val(v),lc(a),rc(b),rev(0){} Node(){} }*nul,*rt,*st[N],t[N]; int n,m,l,r,cnt,a[N]; inli

BZOJ3223: Tyvj 1729 文艺平衡树 [splay]

3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3595  Solved: 2029[Submit][Status][Discuss] Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 Input 第一行为n,m n表示初始序列有n个数,这个序列依次

[BZOJ3223]文艺平衡树 无旋Treap

3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 Input 第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2--n-1,n)  m表示翻转操作次数接下来m行每行两个数[l,r] 数据保证 1<=l<

[题解]bzoj 3223 文艺平衡树

3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3884  Solved: 2235[Submit][Status][Discuss] Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 Input 第一行为n,m n表示初始序列有n个数,这个序列依次

3223: Tyvj 1729 文艺平衡树

3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3473  Solved: 1962[Submit][Status][Discuss] Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 Input 第一行为n,m n表示初始序列有n个数,这个序列依次