题目大意

给一个数列,初始时为 1, 2, 3, ..., n,现在有两种共 m 个操作

  操作1. CUT a b c 表示把数列中第 a 个到第 b 个从原数列中删除得到一个新数列,并将它添加到新数列中第 c 个数的后面

  操作2. FLIP a b 表示把数列中第 a 个数到第 b 个数翻转

经过 m 个操作之后,输出这个数列

1≤n, m≤3*100000

做法分析

这题也不好用线段树做,用 Splay 很快就搞出来了

对于"操作1. CUT a b c" ,只需要将 a-1 旋转到根,b+1旋转成 a-1 的子树,那么 [a, b] 之间的树变成了 b+1 的左子树,将整个子树从原树中删去,并把 b+1 旋转到根。之后把 c 旋转到根,c+1 旋转成 c 的子树,再把刚才删掉的子树添加到 c+1 的左子树上(没添加之前,c+1 的左子树必然为空)

对于“操作2. FLIP a b”,只需要给树中每个节点一个 rev 标记表示是否需要翻转以该节点为根的子树中序遍历所得的数列,和线段树差不多的使用懒操作就行了

还是那些细节问题,在什么时候 pushDown,什么时候 pushUp,写代码的时候一定要想清楚

参考代码

 #include <iostream>
 #include <cstring>
 #include <cstdio>
 #include <queue>

 using namespace std;

 , INF=0x7fffffff;

 struct Splay_Tree {
     struct Node {
         ];
         bool rev;
         inline void init(int _val) {
             val=_val, Size=;
             son[]=son[]=rev=;
         }
     } T[N];
     int fa[N], root;
     queue <int> ans;

     inline void pushUp(int x) {
         T[x].Size=;
         ]) T[x].Size+=T[T[x].son[]].Size;
         ]) T[x].Size+=T[T[x].son[]].Size;
     }

     inline void pushDown(int x) {
         if(!T[x].rev) return;
         ]) T[T[x].son[]].rev^=;
         ]) T[T[x].son[]].rev^=;
         swap(T[x].son[], T[x].son[]);
         T[x].rev=;
     }

     void Rotate(int x, int kind) {
         int y=fa[x], z=fa[y];
         pushDown(y), pushDown(x);
         T[y].son[!kind]=T[x].son[kind], fa[T[x].son[kind]]=y;
         T[x].son[kind]=y, fa[y]=x;
         T[z].son[T[z].son[]==y]=x, fa[x]=z;
         pushUp(y);
     }

     void Splay(int x, int goal) {
         if(x==goal) return;
         while(fa[x]!=goal) {
             int y=fa[x], z=fa[y];
             ]==x, ry=T[z].son[]==y;
             if(z==goal) Rotate(x, rx);
             else {
                 if(rx==ry) Rotate(y, ry);
                 else Rotate(x, rx);
                 Rotate(x, ry);
             }
         }
         pushUp(x);
         ) root=x;
     }

     int Select(int pos, int goal) {
         int u=root;
         pushDown(u);
         ]].Size!=pos) {
             ]].Size>pos) u=T[u].son[];
             else {
                 pos-=T[T[u].son[]].Size+;
                 u=T[u].son[];
             }
             pushDown(u);
         }
         Splay(u, goal);
         return u;
     }

     void Cut(int L, int R, int pos) {
         , ), v=Select(R+, u);
         ];
         fa[x]=, T[v].son[]=;
         Splay(v, );
         u=Select(pos, ), v=Select(pos+, u);
         T[v].son[]=x, fa[x]=v;
         Splay(x, );
     }

     void Reverse(int L, int R) {
         , ), v=Select(R+, u);
         T[T[v].son[]].rev^=;
     }

     void DFS(int u) {
         pushDown(u);
         ]) DFS(T[u].son[]);
         ans.push(T[u].val);
         ]) DFS(T[u].son[]);
     }

     void Display(int n) {
         while(!ans.empty()) ans.pop();
         DFS(root);
         , x; cnt<n; cnt++, ans.pop()) {
             for(x=ans.front(); x==-INF; ans.pop(), x=ans.front());
             printf("%d", x);
             ==n) printf("\n");
             else printf(" ");
         }
     }

     int build(int L, int R) {
         ;
         if(L==R) return L;
         , sL, sR;
         T[mid].son[]=sL=build(L, mid-);
         T[mid].son[]=sR=build(mid+, R);
         fa[sL]=fa[sR]=mid;
         pushUp(mid);
         return mid;
     }

     void init(int n) {
         T[].init(-INF), T[].init(-INF), T[n+].init(-INF);
         ; i<=n+; i++) T[i].init(i-);
         root=build(, n+);
         T[].Size=, T[].son[]=root, fa[root]=, fa[]=;
     }
 } hehe;
 int n, m;
 ];

 int main() {
 //    freopen("in", "r", stdin);
      || m!=-) {
         hehe.init(n);
         , a, b, c; i<m; i++) {
             scanf("%s", cmd);
             ]=='C') {
                 scanf("%d%d%d", &a, &b, &c);
                 hehe.Cut(a, b, c);
             }
             else {
                 scanf("%d%d", &a, &b);
                 hehe.Reverse(a, b);
             }
         }
         hehe.Display(n);
     }
     ;
 }

HDU 3487

题目链接 & AC 通道

HDU 3487 Play with Chain

HDU 3487 Play with Chain(Splay)的更多相关文章

  1. HDU 3487 Play with Chain (splay tree)

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  2. HDU 3487:Play with Chain(Splay)

    http://acm.hdu.edu.cn/showproblem.php?pid=3487 题意:有两种操作:1.Flip l r ,把 l 到 r 这段区间 reverse.2.Cut a b c ...

  3. HDU 3478 Play with Chain (Splay树)

    这种高级数据结构太难搞了.........现在还是先照着别人的代码敲,做模板..........慢慢花时间来弄懂 #include <iostream> #include <algo ...

  4. HDU 1890:Robotic Sort(Splay)

    http://acm.hdu.edu.cn/showproblem.php?pid=1890 题意:有一个无序序列,经过不断地翻转,使得最后的序列是一个升序的序列,而且如果相同数字要使在原本序列靠前的 ...

  5. HDU 3487 Play with Chain 【Splay】

    1-n的序列,有两种操作: 1,将一段区间翻转 2,将一段区间切下来放到剩余序列的第C个数后 采用延迟更新的方法维护区间的翻转,并维护一个size域. 添加一个最大点和一个最小点,防止出界 翻转时,将 ...

  6. 【BZOJ3506】排序机械臂(Splay)

    [BZOJ3506]排序机械臂(Splay) 题面 神TMBZOJ没有题面,感谢SYC的题面 洛谷的题面也不错 题解 对于每次旋转的物体 显然可以预处理出来 现在只要模拟旋转操作就行了 至于在哪里放标 ...

  7. 【BZOJ1500】【NOI2005】维修数列(Splay)

    [BZOJ1500][NOI2005]维修数列(Splay) 题面 不想再看见这种毒瘤题,自己去BZOJ看 题解 Splay良心模板题 真的很简单 我一言不发 #include<iostream ...

  8. 【BZOJ1862】[ZJOI2006]游戏排名系统 (Splay)

    [BZOJ1862][ZJOI2006]游戏排名系统 (Splay) 题面 BZOJ 洛谷 题解 双倍经验题

  9. 【BZOJ1056】[HAOI2008]排名系统(Splay)

    [BZOJ1056][HAOI2008]排名系统(Splay) 题面 BZOJ 洛谷 题解 \(Splay\)随便维护一下就好了,至于名字什么的,我懒得手写哈希表了,直接哈希之后拿\(map\)压. ...

随机推荐

  1. jelq

    初级 The Newbie Routine 5 minutes hot wrap 5 minutes manual stretch (ten 30-second stretches) 10 minut ...

  2. mysql索引的使用[下]

    接着上篇,我们继续来探究索引.这次我们主要来探究关于联合索引的使用和联合.多表查询的规范. 继续看一下数据: mysql> select * from student order by ID d ...

  3. [转]GridView中直接新增行、编辑和删除

    本文转自:http://www.cnblogs.com/gdjlc/archive/2009/11/10/2086951.html .aspx <div><asp:Button ru ...

  4. linux下清除Squid缓存的方法记录

    在日常运维工作中,只要用到squid缓存服务,就会常常被要求清理squid缓存.比如公司领导要求删一篇新闻,新闻是生成的静态.运维人员把服务器上静态的新闻页面删除了后,不料代理服务器上缓存还有.缓存服 ...

  5. mysql导入数据库

     mysql -u root -p bbs < d:\bbs_2011-06-15 --default-character-set=gbk      mysqldump -uroot -p ta ...

  6. qrcode-php生成二维码

    调用PHP QR Code非常简单,如下代码即可生成一张内容为"http://www.baidu.com"的二维码. include 'phpqrcode.php'; QRcode ...

  7. 利用EntityFramework获得双色球数据库

    原文 利用EntityFramework获得双色球数据库 双色球想必大家都很熟悉了,尽管屡买屡不中,但还是会买.以前就想过利用双色球的走势图得到双色球的数据库,至于得到数据库干什么倒没想过,不过对以往 ...

  8. MySQL(二)之服务管理与初始化文件修改和连接MySQL

    上一篇给大家介绍了怎么在linux和windows中安装mysql,本来是可以放在首页的,但是博客园说“安装配置类文件”不让放在首页.接下来给大家介绍一下在linux和windows下MySQL的一下 ...

  9. MySql常用操作语句(1:启动、连接数据库及用户操作)

    下方将个人常用的MySql操作语句(Win7下)总结如下: 1. 启动与关闭数据库 “管理员”权限, MySql安装目录下bin目录//:  1.1 启动 @>net start mysql   ...

  10. [再寄小读者之数学篇](2014-06-22 求极限 [中国科学技术大学2011年高等数学B考研试题])

    设数列 $\sed{x_n}$ 满足 $0<x_1<\pi$, $x_{n+1}=\sin x_n\ (n=1,2,\cdots)$. (1) 证明 $\dps{\vlm{n}x_n}$ ...