模板 文艺平衡树

Splay模板,学完觉得比Treap简单,不过均摊的logn不能可持久化。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define ls ch[0]
  5 #define rs ch[1]
  6 struct trnt{
  7     int ch[2];
  8     int chd;
  9     int wgt;
 10     int fa;
 11     int v;
 12 }tr[10000000];
 13 int root;
 14 int siz;
 15 int n,m;
 16 namespace SPLAY{
 17     void Spushup(int spc)
 18     {
 19         tr[spc].wgt=tr[tr[spc].ch[0]].wgt+tr[tr[spc].ch[1]].wgt+1;
 20         return ;
 21     }
 22     void Spushdown(int spc)
 23     {
 24         if(tr[spc].chd)
 25         {
 26             tr[tr[spc].ch[0]].chd^=1;
 27             tr[tr[spc].ch[1]].chd^=1;
 28             std::swap(tr[tr[spc].ls].ls,tr[tr[spc].ls].rs);
 29             std::swap(tr[tr[spc].rs].ls,tr[tr[spc].rs].rs);
 30             tr[spc].chd=0;
 31         }
 32     }
 33     bool plc(int spc)
 34     {
 35         return tr[tr[spc].fa].rs==spc;
 36     }
 37     void Sroutate(int spc)
 38     {
 39         int f=tr[spc].fa;
 40         bool k=plc(spc);
 41         tr[f].ch[k]=tr[spc].ch[!k];
 42         tr[spc].ch[!k]=f;
 43         tr[tr[f].fa].ch[plc(f)]=spc;
 44         tr[spc].fa=tr[f].fa;
 45         tr[f].fa=spc;
 46         tr[tr[f].ch[k]].fa=f;
 47         Spushup(spc);
 48         Spushup(f);
 49     }
 50     void Splay(int spc,int f)
 51     {
 52         while(tr[spc].fa!=f)
 53         {
 54             int ft=tr[spc].fa;
 55             if(tr[ft].fa==f)
 56             {
 57                 Sroutate(spc);
 58                 break;
 59             }
 60             if(plc(spc)^plc(ft))
 61                 Sroutate(spc);
 62             else
 63                 Sroutate(ft);
 64             Sroutate(spc);
 65         }
 66         if(!f)
 67             root=spc;
 68     }
 69     int Splace(int spc,int rk)
 70     {
 71         Spushdown(spc);
 72         if(tr[tr[spc].ls].wgt>=rk)
 73             return Splace(tr[spc].ls,rk);
 74         else if(tr[tr[spc].ls].wgt+1==rk)
 75             return spc;
 76         else
 77             return Splace(tr[spc].rs,rk-tr[tr[spc].ls].wgt-1);
 78     }
 79     void Supdate(int l,int r)
 80     {
 81         int plc1,plc2;
 82         plc1=Splace(root,l-1);
 83         Splay(plc1,0);
 84         plc2=Splace(root,r+1);
 85         Splay(plc2,plc1);
 86         int spc=tr[plc2].ls;
 87         std::swap(tr[spc].ls,tr[spc].rs);
 88         tr[spc].chd^=1;
 89     }
 90     void Sbuild(int l,int r,int &spc,int f)
 91     {
 92         if(l>r)
 93             return ;
 94         spc=++siz;
 95         int mid=(l+r)>>1;
 96         tr[spc].v=mid;
 97         tr[spc].fa=f;
 98         Sbuild(l,mid-1,tr[spc].ls,spc);
 99         Sbuild(mid+1,r,tr[spc].rs,spc);
100         Spushup(spc);
101         return ;
102     }
103     void Sprint(int spc)
104     {
105         if(!spc)
106             return ;
107         Spushdown(spc);
108         Sprint(tr[spc].ls);
109         printf("%d ",tr[spc].v);
110         Sprint(tr[spc].rs);
111         return ;
112     }
113 }
114 int main()
115 {
116     scanf("%d%d",&n,&m);
117     SPLAY::Sbuild(0,n+1,root,0);
118     for(int i=1;i<=m;i++)
119     {
120         int l,r;
121         scanf("%d%d",&l,&r);
122         SPLAY::Supdate(l+1,r+1);
123     }
124     int org,fin;
125     org=SPLAY::Splace(root,1);
126     SPLAY::Splay(org,0);
127     fin=SPLAY::Splace(root,siz);
128     SPLAY::Splay(fin,root);
129     SPLAY::Sprint(tr[tr[root].rs].ls);
130     puts("");
131     return 0;
132 }

原文地址:https://www.cnblogs.com/blog-Dr-J/p/9572081.html

时间: 2024-10-16 02:35:05

模板 文艺平衡树的相关文章

P3391 【模板】文艺平衡树(Splay)

题目背景 这是一道经典的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

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

题目背景 这是一道经典的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

P3391 【模板】文艺平衡树(Splay)新板子

P3391 [模板]文艺平衡树(Splay) 题目背景 这是一道经典的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,

洛谷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

【模板】文艺平衡树(Splay)

题目背景 这是一道经典的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

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

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

AC日记——文艺平衡树 洛谷 P3391

文艺平衡树 思路: splay翻转操作模板: 虚拟最左最右端点,然后每次都把l翻转到root,r+2翻转到root的右节点: 然后在r+2的左节点上打标记: 标记需要在旋转,rank,print时下放: 建树需要用完全平衡二叉树: 来,上代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define m

[Splay]luogu P3391 文艺平衡树

题目描述 https://www.luogu.org/problemnew/show/P3391 分析 文艺平衡树 一道大家熟知的splay区间翻转模板题 基于splay的区间翻转,我们要做的只有这些: 1.像线段树一样打翻转标记,不过由于翻转是可以抵消的,所以可以采取位运算节省时间 2.翻转只需要逐层翻转即可,正确性已有论证 3.对于区间如何确定的问题,我们只需要将l-1节点旋至根,r+1节点旋至根下即可 4.对于1~x或x~n区间的操作,我们还需要0和n+1这两个哨兵节点 #include

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