• P3391 【模板】文艺平衡树FHQ treap


    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

    说明

    code

     1 #include<cstdio>
     2 #include<algorithm>
     3 
     4 using namespace std;
     5 
     6 const int N = 500100;
     7 int ch[N][2],tag[N],val[N],siz[N],key[N];
     8 int tn,Root,n,m;
     9 
    10 inline char nc() {
    11     static char buf[100000],*p1 = buf,*p2 = buf;
    12     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF : *p1++;
    13 }
    14 inline int read() {
    15     int x = 0,f = 1;char ch = nc();
    16     for (; ch<'0'||ch>'9'; ch = nc()) 
    17         if (ch=='-') f = -1;
    18     for (; ch>='0'&&ch<='9'; ch = nc()) 
    19         x = x*10+ch-'0';
    20     return x * f;
    21 }
    22 inline void pushup(int x) {
    23     siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;
    24 }
    25 inline void pushdown(int x) {
    26     if (tag[x]) {       
    27         tag[ch[x][0]] ^= 1;tag[ch[x][1]] ^= 1;
    28         swap(ch[x][0],ch[x][1]);
    29         tag[x] ^= 1;
    30     }
    31 }
    32 inline int makenode(int x) {
    33     ++tn;siz[tn] = 1;val[tn] = x;key[tn] = rand();return tn;
    34 }
    35 int merge(int x,int y) {
    36     if (!x || !y) return x + y;
    37     pushdown(x);pushdown(y);
    38     if (key[x] < key[y]) {
    39         ch[x][1] = merge(ch[x][1],y);
    40         pushup(x);return x;
    41     }
    42     else {
    43         ch[y][0] = merge(x,ch[y][0]);
    44         pushup(y);return y;
    45     }
    46 }
    47 void split(int now,int k,int &x,int &y) {
    48     if (!now) x = y = 0;
    49     else {
    50         pushdown(now);
    51         if (k<=siz[ch[now][0]]) 
    52             y = now,split(ch[now][0],k,x,ch[now][0]);
    53         else 
    54             x = now,split(ch[now][1],k-siz[ch[now][0]]-1,ch[now][1],y);
    55         pushup(now);
    56     }
    57 }
    58 inline void rever(int l,int r) {
    59     int a,b,c,d;
    60     split(Root,r,a,b);
    61     split(a,l-1,c,d);
    62     tag[d] ^= 1;
    63     Root = merge(merge(c,d),b);    
    64 }
    65 void print(int x) {
    66     if (!x) return ;
    67     pushdown(x);
    68     print(ch[x][0]);
    69     printf("%d ",val[x]);
    70     print(ch[x][1]);
    71 }
    72 int main() {
    73     n = read(),m = read();
    74     for (int i=1; i<=n; ++i) {
    75         Root = merge(Root,makenode(i));
    76     }
    77     while (m--) {
    78         int a = read(),b = read();
    79         rever(a,b);
    80     }
    81     print(Root);
    82     return 0;
    83 }

    网上学的另一种建树方法:

     1 int build(int l,int r)
     2 {
     3     if (l>r) return 0;
     4     int mid=(l+r)>>1,v=mid;
     5     int now=makenode(v);
     6     ch[now][0]=build(l,mid-1);
     7     ch[now][1]=build(mid+1,r);
     8     pushup(now);
     9     return now;
    10 }
    11 Root = build(1,n);

    虽然可能不满足堆的性质,但是,堆在这个过程中只是调节树的平衡的,所以还是可以过的

    板子的发展史。。。

     1 #include<cstdio>
     2 #include<algorithm>
     3 
     4 using namespace std;
     5 
     6 const int N = 500100;
     7 int ch[N][2],tag[N],val[N],siz[N],key[N];
     8 int tn,Root,n,m;
     9 
    10 inline char nc() {
    11     static char buf[100000],*p1 = buf,*p2 = buf;
    12     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF : *p1++;
    13 }
    14 inline int read() {
    15     int x = 0,f = 1;char ch = nc();
    16     for (; ch<'0'||ch>'9'; ch = nc()) 
    17         if (ch=='-') f = -1;
    18     for (; ch>='0'&&ch<='9'; ch = nc()) 
    19         x = x*10+ch-'0';
    20     return x * f;
    21 }
    22 inline void pushup(int x) {
    23     siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;
    24 }
    25 inline void pushdown(int x) {
    26     if (tag[x]) {       
    27         tag[ch[x][0]] ^= 1;tag[ch[x][1]] ^= 1;
    28         swap(ch[x][0],ch[x][1]);
    29         tag[x] ^= 1;
    30     }
    31 }
    32 inline int makenode(int x) {
    33     ++tn;siz[tn] = 1;val[tn] = x;key[tn] = rand();return tn;
    34 }
    35 int merge(int x,int y) {
    36     if (!x || !y) return x + y;
    37     if (key[x] < key[y]) {
    38         pushdown(x);
    39         ch[x][1] = merge(ch[x][1],y);
    40         pushup(x);return x;
    41     }
    42     else {
    43         pushdown(y);
    44         ch[y][0] = merge(x,ch[y][0]);
    45         pushup(y);return y;
    46     }
    47 }
    48 void split(int now,int k,int &x,int &y) {
    49     if (!now) x = y = 0;
    50     else {
    51         pushdown(now);
    52         if (k<=siz[ch[now][0]]) 
    53             y = now,split(ch[now][0],k,x,ch[now][0]);
    54         else 
    55             x = now,split(ch[now][1],k-siz[ch[now][0]]-1,ch[now][1],y);
    56         pushup(now);
    57     }
    58 }
    59 inline void rever(int l,int r) {
    60     int a,b,c,d;
    61     split(Root,r,a,b);
    62     split(a,l-1,c,d);
    63     tag[d] ^= 1;
    64     Root = merge(merge(c,d),b);    
    65 }
    66 void print(int x) {
    67     if (!x) return ;
    68     pushdown(x);
    69     print(ch[x][0]);
    70     printf("%d ",val[x]);
    71     print(ch[x][1]);
    72 }
    73 int main() {
    74     n = read(),m = read();
    75     for (int i=1; i<=n; ++i) {
    76         Root = merge(Root,makenode(i));
    77     }
    78     while (m--) {
    79         int a = read(),b = read();
    80         rever(a,b);
    81     }
    82     print(Root);
    83     return 0;
    84 }
    View Code
  • 相关阅读:
    RPM Repositories for CentOS 6, 7 and 8
    oracle user clone script
    在 Linux 上安装和配置 VNC 服务器
    阿里云ORACLE RAC共享磁盘组扩容实战笔记
    如何在 SQL Server 中创建和配置链接服务器以连接到 MySQL
    oracle 11.2.0.4 windows64位下载
    How To Drop And Recreate Temp Tablespace In Oracle
    查询mysql没有主键的表
    hadoop常用端口及定义方法
    MySQL主从复制中问题排查过程总结
  • 原文地址:https://www.cnblogs.com/mjtcn/p/8029680.html
Copyright © 2020-2023  润新知