zoukankan      html  css  js  c++  java
  • 3223. 文艺平衡树【平衡树-splay】

    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

    板子啊,常规操作

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #define MAXN (100000+10)
      5 using namespace std;
      6 int Father[MAXN];
      7 int Son[MAXN][2];
      8 int Size[MAXN];
      9 int Smark[MAXN];
     10 int a[MAXN];
     11 int Key[MAXN];
     12 int Root;
     13 int n,m,l,r;
     14 int Get(int x)
     15 {
     16     return Son[Father[x]][1]==x;
     17 }
     18 
     19 void Update(int x)
     20 {
     21     Size[x]=Size[Son[x][1]]+Size[Son[x][0]]+1;
     22 }
     23 
     24 void Pushdown(int x)
     25 {
     26     if (x && Smark[x])
     27     {
     28         Smark[Son[x][0]]^=1;
     29         Smark[Son[x][1]]^=1;
     30         swap(Son[x][0],Son[x][1]);
     31         Smark[x]=0;
     32     }
     33 }
     34 
     35 void Rotate(int x)
     36 {
     37     Pushdown(Father[x]);
     38     Pushdown(x);
     39     int fa=Father[x];
     40     int fafa=Father[fa];
     41     int wh=Get(x);
     42     
     43     Son[fa][wh]=Son[x][wh^1];
     44     Father[fa]=x;
     45     if (Son[fa][wh]) Father[Son[fa][wh]]=fa;
     46     
     47     Father[x]=fafa;
     48     Son[x][wh^1]=fa;
     49     if (fafa) Son[fafa][Son[fafa][1]==fa]=x;
     50     
     51     Update(fa);
     52     Update(x);
     53 }
     54 
     55 void Splay(int x,int tar)
     56 {
     57     for (int fa;(fa=Father[x])!=tar;Rotate(x))
     58         if (Father[fa]!=tar)
     59             Rotate(Get(fa)==Get(x)?fa:x);
     60     if (!tar) Root=x;
     61 }
     62 
     63 void Build (int l,int r,int fa)
     64 {
     65     if (l>r) return;
     66     int mid=(l+r)/2;
     67     if (mid<fa) Son[fa][0]=mid;
     68     if (mid>fa) Son[fa][1]=mid;
     69     Father[mid]=fa;
     70     Size[mid]=1;
     71     Key[mid]=a[mid];
     72     if (l==r) return;
     73     Build(l,mid-1,mid);
     74     Build(mid+1,r,mid);
     75     Update(mid);
     76 }
     77 
     78 int Findx(int x)
     79 {
     80     int now=Root;
     81     while (1)
     82     {
     83         Pushdown(now);
     84         if (x<=Size[Son[now][0]])
     85             now=Son[now][0];
     86         else
     87         {
     88             x-=Size[Son[now][0]];
     89             if (x==1) return now;
     90             x-=1;
     91             now=Son[now][1];
     92         }
     93     }
     94 }
     95 
     96 void Rever(int l,int r)
     97 {
     98     int f1=Findx(l);
     99     int f2=Findx(r+2);
    100     Splay(f1,0);
    101     Splay(f2,f1);
    102     Smark[Son[Son[Root][1]][0]]^=1;
    103 }
    104 
    105 void Write(int x)
    106 {
    107     Pushdown(x);
    108     if (Son[x][0]) Write(Son[x][0]);
    109     if (x>=2 && x<=n+1) printf("%d ",Key[x]);
    110     if (Son[x][1]) Write(Son[x][1]);
    111 }
    112 
    113 int main()
    114 {
    115     scanf("%d%d",&n,&m);
    116     for (int i=2;i<=n+1;++i)
    117         a[i]=i-1;
    118     Build(1,n+2,0);Root=(n+3)/2;
    119     for (int i=1;i<=m;++i)
    120     {
    121         scanf("%d%d",&l,&r);
    122         if (l>=r) continue;
    123         Rever(l,r);
    124     }
    125     Write(Root);
    126 }
  • 相关阅读:
    Largest Rectangle in Histogram
    Valid Sudoku
    Set Matrix Zeroes
    Unique Paths
    Binary Tree Level Order Traversal II
    Binary Tree Level Order Traversal
    Path Sum II
    Path Sum
    Validate Binary Search Tree
    新手程序员 e
  • 原文地址:https://www.cnblogs.com/refun/p/8678699.html
Copyright © 2011-2022 走看看