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

题面

https://www.luogu.org/problem/P3391

题解

#include<cstdio>
#include<iostream>
using namespace std;

const int start = 100050 ;
struct node {
  int ch[2],fa;
  int v,siz;
  bool turn;
} a[100500];

int n,m,cnt;

bool opt(int x) {
  return a[a[x].fa].ch[1]==x;
}

void pushdown(int now) {
  if (!now || !a[now].turn) return;
  a[now].turn=false;
  swap(a[a[now].ch[0]].ch[0],a[a[now].ch[0]].ch[1]); a[a[now].ch[0]].turn^=1;
  swap(a[a[now].ch[1]].ch[0],a[a[now].ch[1]].ch[1]); a[a[now].ch[1]].turn^=1;
}

void rotate(int x) {
  int y=a[x].fa,z=a[y].fa; bool s=opt(x);
  pushdown(z); pushdown(y); pushdown(x);
  a[z].ch[opt(y)]=x; a[x].fa=z;
  a[y].ch[s]=a[x].ch[1^s]; a[a[x].ch[1^s]].fa=y;
  a[y].fa=x; a[x].ch[1^s]=y;
  a[y].siz=a[a[y].ch[0]].siz+a[a[y].ch[1]].siz+1;
  a[x].siz=a[a[x].ch[0]].siz+a[a[x].ch[1]].siz+1;
}

void splay(int now,int to) {
  while (a[now].fa!=to) {
    if (a[a[now].fa].fa==to) rotate(now);
    else {
      if (opt(now)==opt(a[now].fa)) rotate(a[now].fa),rotate(now);
      else rotate(now),rotate(now);
    }
  }
}

void insert(int x) {
  int now=start;
  while (a[now].ch[x>a[now].v]) a[now].siz++,now=a[now].ch[x>a[now].v];
  a[now].siz++; a[now].ch[x>a[now].v]=++cnt;
  a[cnt]=(node){0,0,now,x,1,0};
  splay(cnt,start);
}

int findbyrank(int rk) {
  int cnr=0,now=start;
  while (1) {
    pushdown(now);
    if (cnr+a[a[now].ch[0]].siz==rk) return now;
    else {
      if (cnr+a[a[now].ch[0]].siz>rk) now=a[now].ch[0];
      else cnr+=a[a[now].ch[0]].siz+1,now=a[now].ch[1];
    }
  }
}

void print(int now) {
  if (!now) return;
  pushdown(now);
  print(a[now].ch[0]);
  if (a[now].v>=1 && a[now].v<=n) printf("%d ",a[now].v);
  print(a[now].ch[1]);
}

int main(){
  int i,l,r;
  scanf("%d %d",&n,&m);
  a[start]=(node){0,0,0,-1,1,0};
  cnt=0;
  for (i=0;i<=n+1;i++) {
    //printf("%d\n",i);
    insert(i);
  }
  for (i=1;i<=m;i++) {
    //printf("%d\n",i);
    scanf("%d %d",&l,&r);
    int lx=findbyrank(l),rx=findbyrank(r+2);
    splay(lx,start);
    splay(rx,lx);
    swap(a[a[rx].ch[0]].ch[0],a[a[rx].ch[0]].ch[1]);
    a[a[rx].ch[0]].turn^=1;
  }
  print(start);
}

 

posted @ 2019-08-28 23:57  HellPix  阅读(142)  评论(0编辑  收藏  举报