C06【模板】FHQ Treap P3391 文艺平衡树

视频链接:264【模板】FHQ Treap P3391 文艺平衡树_哔哩哔哩_bilibili

 

 Luogu P3391 【模板】文艺平衡树

#include <iostream>
using namespace std;

const int N=100010;
struct node{
  int l,r; //左右儿子
  int val; //树的权值 
  int key; //堆的随机值
  int size; //子树大小
  int tag; //懒标记
}tr[N];
int n,m,root,idx;

int newnode(int v){
  tr[++idx].val=v;
  tr[idx].key=rand();
  tr[idx].size=1;
  return idx;
}
void pushup(int p){
  tr[p].size=tr[tr[p].l].size
        +tr[tr[p].r].size+1;
}
void pushdown(int p){
  if(!tr[p].tag||!p) return;
  swap(tr[p].l, tr[p].r);
  tr[tr[p].l].tag ^= 1;
  tr[tr[p].r].tag ^= 1;
  tr[p].tag = 0;
}
void split(int p,int k,int &x,int &y){
  if(!p) {x=y=0; return;}
  pushdown(p);
  if(k>tr[tr[p].l].size){
    k-=tr[tr[p].l].size+1;
    x=p;
    split(tr[p].r,k,tr[p].r,y);
  } 
  else{
    y=p;
    split(tr[p].l,k,x,tr[p].l);
  }
  pushup(p);
}
int merge(int x,int y){
  if(!x||!y) return x+y;
  if(tr[x].key<tr[y].key){
    pushdown(x);
    tr[x].r=merge(tr[x].r,y);
    pushup(x); return x;
  }
  else{
    pushdown(y);
    tr[y].l=merge(x,tr[y].l);
    pushup(y); return y;
  }
}
void reverse(int l,int r){
  int x,y,z;
  split(root,r,x,z);
  split(x,l-1,x,y);
  tr[y].tag ^= 1; //标记
  root=merge(merge(x,y),z);
}
void output(int p){
  if(!p) return;
  pushdown(p);
  output(tr[p].l);
  printf("%d ",tr[p].val);
  output(tr[p].r);
}
int main(){
  srand(time(0));
  scanf("%d%d",&n,&m);
  for(int i=1;i<=n;i++)
    root=merge(root,newnode(i));
  for(int x,y,i=1;i<=m;i++){
    scanf("%d%d",&x,&y);
    reverse(x, y);
  }
  output(root);
  return 0;
}

 

posted @ 2022-07-24 23:31  董晓  阅读(496)  评论(0编辑  收藏  举报