zoukankan      html  css  js  c++  java
  • 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,n1,n) m表示翻转操作次数

    接下来m行每行两个数 [l,r][l,r] 数据保证 1 leq l leq r leq n1lrn

    输出格式:

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

    输入输出样例

    输入样例#1:
    5 3
    1 3
    1 3
    1 4
    输出样例#1:
    4 3 2 1 5

    说明

    n, m leq 100000n,m100000

    code

      1 #include<cstdio>
      2 #include<algorithm>
      3 
      4 using namespace std;
      5 
      6 const int MAXN = 100100;
      7 int fa[MAXN],ch[MAXN][2],tag[MAXN],siz[MAXN],id[MAXN];
      8 int n,m,root,sz;
      9 
     10 int read()
     11 {
     12     int x = 0;char ch = getchar();
     13     while (ch<'0'||ch>'9') ch = getchar();
     14     while (ch>='0'&&ch<='9') x = x*10+ch-'0',ch = getchar();
     15     return x;
     16 }
     17 void pushup(int x)
     18 {
     19     siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;
     20 }
     21 void pushdown(int x)
     22 {
     23     if (tag[x])
     24     {
     25         tag[ch[x][0]] ^= 1;
     26         tag[ch[x][1]] ^= 1;
     27         swap(ch[x][0],ch[x][1]);
     28         tag[x] = 0;
     29     }
     30 }
     31 int son(int x)
     32 {
     33     return ch[fa[x]][1]==x;
     34 }
     35 void rotate(int x)
     36 {
     37     int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b];
     38     if (z) ch[z][c] = x;else root = x;fa[x] = z;
     39     if (a) fa[a] = y;ch[y][b] = a;
     40     ch[x][!b] = y;fa[y] = x;
     41     pushup(y);
     42 }
     43 void splay(int &x,int rt)
     44 {
     45     while (fa[x]!=rt)
     46     {
     47         int y = fa[x],z = fa[y];
     48         if (z==rt) rotate(x);
     49         else
     50         {
     51             if (son(x)==son(y)) rotate(y),rotate(x);
     52             else rotate(x), rotate(x);
     53         }
     54     }
     55     pushup(x);
     56 }
     57 int getkth(int rt,int k)
     58 {
     59     pushdown(rt);
     60     int l = ch[rt][0],r = ch[rt][1];
     61     if (k==siz[l]+1) return rt;
     62     else if (k<siz[l]+1) return getkth(l,k);
     63     else return getkth(r,k-siz[l]-1);
     64 }
     65 void reverse(int l,int r)
     66 {
     67     int tl = getkth(root,l),tr = getkth(root,r+2);
     68     splay(tl,0);splay(tr,tl);
     69     tag[ch[tr][0]] ^= 1;
     70 }
     71 void build(int l,int r,int f)
     72 {
     73     if (l>r) return ;
     74     int now = id[l],last = id[f];
     75     if (l==r) 
     76     {
     77         fa[now] = last;
     78         siz[now] = 1;
     79         if (l<f) ch[last][0] = now;
     80         else ch[last][1] = now;
     81         return ;
     82     }
     83     int mid = (l+r)>>1;
     84     now = id[mid];
     85     build(l,mid-1,mid);
     86     build(mid+1,r,mid);
     87     fa[now] = last;
     88     pushup(mid);
     89     if (mid<f) ch[last][0] = now;
     90     else ch[last][1] = now;
     91 }
     92 int main()
     93 {
     94     n = read();m = read();
     95     for (int i=1; i<=n+2; ++i) id[i] = ++sz;
     96     build(1,n+2,0);root = (n+3)>>1;        
     97     while (m--)
     98     {
     99         int x = read(),y = read();
    100         reverse(x,y);
    101     }
    102     for (int i=2; i<=n+1; ++i)
    103         printf("%d ",getkth(root,i)-1);
    104     return 0;
    105 }
  • 相关阅读:
    除法
    01.python对象
    00.基础入门
    00.斐波那契数列第n项
    16.分治排序
    15.快速排序
    14.插入排序--希尔排序(缩小增量排序)
    13.插入排序--直接插入排序(简单插入排序)
    12.选择排序
    11.冒泡排序
  • 原文地址:https://www.cnblogs.com/mjtcn/p/7352329.html
Copyright © 2011-2022 走看看