Treap永不旋轉!!![維修數列]

本文详细介绍了如何在O(n)时间内构造Treap,并探讨了Treap在不旋转节点的情况下实现区间插入、删除、反转和赋值等操作。特别强调了使用栈解决构造问题的策略,以及Treap保持中序遍历为原序列的特性。
摘要由CSDN通过智能技术生成

前言

Splay是會轉的的好,Treap是不會轉的妙,我們不用轉也能實現神奇的操作
在這裡比較複雜的是插入區間的操作,這是Treap沒有嘗試過的

如何 O(n) O ( n ) 構造Treap?

Splay可以遞歸構造,但是Treap有key的問題,顯然不能那樣構造
那怎麼構造呢?
我們利用棧來解決這個問題
我們將每次構造出來的節點放到棧裏,當我們再次要構造一個新節點時,我們和棧頂節點比較,有兩種情況停止比較

  1. 棧頂元素key值的優先度高於新節點
  2. 棧空了

我們將最後一個彈出的節點接在新節點的左兒子上
如果棧未空,我們就將新節點接在棧頂的右兒子上
最後將新節點壓入棧
不要忘了將每個節點都Pushup一下
這個操作玄學滿足中序遍曆為原序列,而且造出了一個平衡的Treap
不知道是誰想出的神奇操作

inline node *build(int k)
{
  int top=0,a;
  for(int i=1;i<=k;i++)
  {
    read(a);
    node *temp=new node(a),*last=nil;
    while(top&&stack[top]->key>temp->key)
    stack[top]->push_up(),last=stack[top],stack[top--]=nil;
    if(top)stack[top]->son[1]=temp;
    temp->son[0]=last,stack[++top]=temp;
  }
  while(top)
  stack[top--]->push_up();
  return stack[1];
}

只有這裡最難
下面我把每個函數分開發上來

節點定義

struct node
{
  int val,key,size,sum,maxsum,lmax,rmax;
  bool rev,same;
  node *son[2];
  node(int x);
  node(){}
  ~node();
  inline void push_up();
  inline void push_down();
  inline void push_rev();
  inline void push_same(int x);
}*nil=new node(0),*Root,*stack[MAXN];

pair模板

template<class a,class b>class Pair
{
public:
  a first;
  b second;
  Pair(){}
  Pair(a x,b y){
  first=x,second=y;}
};

讀入輸出優化

inline void read(int &x)
{
  int s=0,w=1;
  char c=getchar();
  while(c<'0'||c>'9'){
  if(c=='-')w=-1;c=getchar();}
  while(c<='9'&&c>='0'){s=(s<<3)+(s<<1)+c-'0';c=getchar();}
  x=s*w;
}
inline void write(int x)
{
  if(x<0)putchar('-'),x=-x;
  if(x>9)write(x/10);
  putchar(x%10+'0');
}</
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值