• 【splay】文艺平衡树 BZOJ 3223


    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<=r<=n 

    Output

    输出一行n个数字,表示原始序列经过m次变换后的结果 

    Sample Input

    5 3

    1 3

    1 3
    1 4

     

    Sample Output

    4 3 2 1 5

    HINT

    N,M<=100000

    思路

       一看就知道是Splay。。。。如此经典。也是我写过的第二道splay。第一道是文本编辑器,但是本地测AC,提交的话就WA到死。。

       只有区间翻转操作,如果我们要翻转[L,R]的话,就将L-1转到根,再将第R+1大的转到根的右子树。把根的右子树的左子树打上翻转标记就行了。

       [1,L-1]和[R+1,n]都被转到别的地方去了,所以不会被旋转。

       然后别的都是splay的基本操作啦~只要每次记得push_down就行啦~

      1 #include <iostream>
      2 #include <cstring>
      3 #include <string>
      4 #include <cstdio>
      5 #include <cstdlib>
      6 #include <cmath>
      7 #include <algorithm>
      8 #include <queue>
      9 #include <stack>
     10 #include <map>
     11 #include <set>
     12 #include <list>
     13 #include <vector>
     14 #include <ctime>
     15 #include <functional>
     16 #define pritnf printf
     17 #define scafn scanf
     18 #define sacnf scanf
     19 #define For(i,j,k) for(int i=(j);i<=(k);(i)++)
     20 #define Clear(a) memset(a,0,sizeof(a))
     21 using namespace std;
     22 typedef unsigned int Uint;
     23 const int INF=0x3fffffff;
     24 ///==============struct declaration==============
     25 struct Node{
     26    int Val;bool Rev;
     27    int siz;
     28    Node *lc,*rc;
     29    Node(){lc=rc=NULL;Rev=false;siz=1;}
     30 };
     31 ///==============var declaration=================
     32 const int MAXN=100050;
     33 int n,q;
     34 int num[MAXN];
     35 Node *root=NULL;
     36 ///==============function declaration============
     37 void BuildTree(int l,int r,Node *&o);
     38 int find_kth(int rank,Node *&o);
     39 void Splay(int Rank,Node *&o);
     40 void Rrotate(Node *&x);void Lrotate(Node *&x);
     41 void push_down(Node *&x);void Output(Node *&x);
     42 void update(Node *&x);void TestOutput(Node *&x);
     43 ///==============main code=======================
     44 int main()
     45 {
     46 #define FILE__
     47 #ifdef FILE__
     48    freopen("input","r",stdin);
     49    freopen("output","w",stdout);
     50 #endif
     51    scanf("%d%d",&n,&q);
     52    BuildTree(0,n+1,root);//TestOutput(root);printf("
    ");
     53    while (q--){
     54       int L,R;scanf("%d%d",&L,&R);
     55       if (L==R)   continue;
     56       Splay(L,root);
     57       if (root->lc==NULL)
     58          Splay(R+1,root->rc);
     59       else
     60          Splay(R+1-root->lc->siz,root->rc);
     61       if (root->rc!=NULL&&root->rc->lc!=NULL)
     62          root->rc->lc->Rev^=1;
     63       //TestOutput(root);printf("
    ");
     64    }
     65    Output(root);
     66    return 0;
     67 }
     68 ///================fuction code====================
     69 void BuildTree(int l,int r,Node *&o){
     70    int m=(l+r)>>1;
     71    o=new(Node);o->Val=m;
     72    if (l==r)   return;
     73    if (m>l) BuildTree(l,m-1,o->lc);
     74    if (m<r) BuildTree(m+1,r,o->rc);
     75    if (o->lc!=NULL)  o->siz+=o->lc->siz;
     76    if (o->rc!=NULL)  o->siz+=o->rc->siz;
     77 }
     78 void Lrotate(Node *&x){
     79    push_down(x);push_down(x->lc);
     80    Node *y=x->lc;
     81    x->lc=y->rc;
     82    y->rc=x;x=y;
     83    update(x->rc);update(x);
     84 }
     85 void Rrotate(Node *&x){
     86    push_down(x);push_down(x->rc);
     87    Node *y=x->rc;
     88    x->rc=y->lc;
     89    y->lc=x;x=y;
     90    update(x->lc);update(x);
     91 }
     92 void push_down(Node *&x){
     93    if (x->Rev){
     94       swap(x->lc,x->rc);
     95       x->Rev=false;
     96       if (x->lc!=NULL)  x->lc->Rev^=1;
     97       if (x->rc!=NULL)  x->rc->Rev^=1;
     98    }
     99 }
    100 void update(Node *&x){
    101    x->siz=1;
    102    if (x->lc!=NULL)  x->siz+=x->lc->siz;
    103    if (x->rc!=NULL)  x->siz+=x->rc->siz;
    104 }
    105 void Splay(int Rank,Node *&o){
    106    int ls=0;push_down(o);
    107    if (o->lc!=NULL)  ls=o->lc->siz;
    108    if (Rank==ls+1)   return;
    109    if (Rank>ls+1){
    110       Splay(Rank-ls-1,o->rc);
    111       Rrotate(o);
    112    }
    113    else{
    114       Splay(Rank,o->lc);
    115       Lrotate(o);
    116    }
    117 }
    118 void Output(Node *&x){
    119    if (x==NULL) return;
    120    push_down(x);
    121    Output(x->lc);
    122    if (x->Val!=0&&x->Val!=n+1)
    123       printf("%d ",x->Val);
    124    Output(x->rc);
    125 }
    126 void TestOutput(Node *&x){
    127    if (x==NULL)  return;
    128    if (!x->Rev){
    129       printf("%d(",x->Val);
    130       TestOutput(x->lc);
    131       printf(",");
    132       TestOutput(x->rc);
    133       printf(")");
    134    }
    135    else{
    136       printf("%d(",x->Val);
    137       TestOutput(x->rc);
    138       printf(",");
    139       TestOutput(x->lc);
    140       printf(")");
    141    }
    142 }
    BZOJ 3223

      那个TestOutput是我用来在不改变标记的情况下看数的结构的。

  • 相关阅读:
    LeetCode 38. 外观数列
    LeetCode 33. 搜索旋转排序数组
    LeetCode 31. 下一个排列
    LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置
    LeetCode 29. 两数相除
    LeetCode 22. 括号生成
    LeetCode 1. 两数之和
    LeetCode 17. 电话号码的字母组合
    LeetCode 18. 四数之和
    LeetCode 16. 最接近的三数之和
  • 原文地址:https://www.cnblogs.com/Houjikan/p/4329490.html
Copyright © 2020-2023  润新知