bzoj3223 文艺平衡树 treap

题意:求多次区间反转后的序列

一眼splay,我用了可持久treap实现的。

速度也不错 2008ms

这么想想splay好像没什么用了(大雾@lct

#include<iostream>
#include<cstdio>
#include<cstdlib>
#define N 200005
#define mp make_pair
#define pa pair<int,int>
using namespace std;
struct treap{int val,ls,rs,sz,key,flip;}t[N];
int n,m,root=0,num=0,cnt=0;
int v[N];
void pushdown(int x){
    if(!t[x].flip) return;
    t[t[x].ls].flip^=t[x].flip;
    t[t[x].rs].flip^=t[x].flip;
    t[x].flip=0;
    swap(t[x].ls,t[x].rs);
}
void pushup(int x) {t[x].sz=t[t[x].ls].sz+t[t[x].rs].sz+1;}
pa split(int a,int k){
    pa tmp;
    if(k==0) return mp(0,a);
    pushdown(a);int ls=t[a].ls,rs=t[a].rs;
    if(k==t[ls].sz) {t[a].ls=0;pushup(a);return mp(ls,a);}
    if(k==t[ls].sz+1) {t[a].rs=0;pushup(a);return mp(a,rs);}
    if(k<t[ls].sz) {tmp=split(ls,k);t[a].ls=tmp.second;pushup(a);return mp(tmp.first,a);}
    if(k>t[ls].sz+1) {tmp=split(rs,k-t[ls].sz-1);t[a].rs=tmp.first;pushup(a);return mp(a,tmp.second);}
}
int merge(int a,int b){
    if(a==0 || b==0) return a+b;
    if(t[a].key<t[b].key) {pushdown(a);t[a].rs=merge(t[a].rs,b);pushup(a);return a;}
    else {pushdown(b);t[b].ls=merge(a,t[b].ls);pushup(b);return b;}
}
void ins(int &now,int x){
    t[++num].val=x;
    t[num].key=rand();
    t[num].sz=1;
    pushdown(now);
    now=merge(now,num);
}
void dfs(int x){
    if(x==0) return;
    if(t[x].flip) pushdown(x);
    dfs(t[x].ls);
    v[++cnt]=x;
    dfs(t[x].rs);
}
int main(){
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) ins(root,i);
    for(int i=1;i<=m;i++){
        int l,r;
        scanf("%d%d",&l,&r);
        pa tmp1=split(root,l-1);
        pa tmp2=split(tmp1.second,r-l+1);
        t[tmp2.first].flip^=1;
        root=merge(tmp1.first,tmp2.first);
        root=merge(root,tmp2.second);
    }
    dfs(root);
    for(int i=1;i<=cnt;i++) printf("%d ",v[i]);puts("");
    return 0;
}
时间: 2024-10-05 05:50:03

bzoj3223 文艺平衡树 treap的相关文章

[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<

[BZOJ3223]文艺平衡树

以前看着非旋treap的题解写了一发,没有真正理解 最近补了一下splay,于是用来练手 因为是区间翻转,子树大小不变,所以pushup时儿子对父亲没有影响 因此splay($x$)之前只需一路从根pushdown到$x$即可,不需要pushdown儿子 由于pushdown时交换儿子破坏了二叉搜索树的性质,故splay($x$)应该改为splay($k$),即splay排名第几的节点而不是splay节点编号 #include<stdio.h> int ch[100010][2],fa[100

JZYZOJ1998 [bzoj3223] 文艺平衡树 splay 平衡树

http://172.20.6.3/Problem_Show.asp?id=1998 平衡树区间翻转的板子,重新写一遍,给自己码一个板子. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<cstdlib> 7 using namespace std; 8 cons

[bzoj3223]文艺平衡树[splay]

//BY HZWER 1 #include<iostream> 2 #include<cstdio> 3 4 using namespace std; 5 6 inline int read() 7 { 8 int x=0,f=1;char ch=getchar(); 9 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 10 while(ch>='0'&&ch<='9'){x=x*10

[bzoj3223]文艺平衡树(splay区间反转模板)

解题关键:splay模板题. #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> using namespace std; typedef long long ll; const int N = 100005; int ch[N][2],par[N],val[N],cnt[

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][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个数,这个序列

洛谷P3391 【模板】文艺平衡树(Splay)(FHQ Treap)

题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 输入输出格式 输入格式: 第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2, \cdots n-1,n)(1,2,?n−1,n) m表示翻转操作次数 接下来m行每行两个数 [l,r][l,r] 数据保证 1 \leq l \leq r

bzoj3223Tyvj 1729 文艺平衡树

bzoj3223Tyvj 1729 文艺平衡树 题意: 一个数列,支持区间翻转操作. 题解: splay裸题.注意涉及到区间操作的一般用splay不用treap. 代码: 1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #define inc(i,j,k) for(int i=j;i<=k;i++) 5 #define fa(x) nds[x].fa 6 #define ch(x,