http://acm.hdu.edu.cn/showproblem.php?pid=3487

题意:有两种操作:1、Flip l r ,把 l 到 r 这段区间 reverse。2、Cut a b c ,把 a 到 b 这段区间切掉,再把这段区间接到切掉后的第 c 个数的后面。

思路:做完了上一道变态题目,做这道题目如鱼得水。Cut的时候就是把a 到 b 放到keytree的位置,记录一下当前keytree的值,然后切掉,再把切掉后的第 c 个数转到 root 的位置,再把这个记录的值重新连接回去。要注意当全部询问结束了,要把所有的rev标记pushdown。

 #include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <iostream>
#include <stack>
#include <map>
#include <queue>
using namespace std;
#define N 300100
#define INF 0x3f3f3f3f
#define lson ch[x][0]
#define rson ch[x][1]
#define keytree ch[ch[root][1]][0] struct SplayTree
{
int num[N], rev[N], ch[N][], fa[N], val[N], sz[N];
int n, root, cnt, ans[N], tol; void PushDown(int x)
{
if(rev[x]) {
swap(lson, rson);
if(lson) rev[lson] ^= ;
if(rson) rev[rson] ^= ;
rev[x] = ;
}
} void PushUp(int x)
{
sz[x] = sz[lson] + sz[rson] + ;
} int NewNode(int w, int f, int kind)
{
int x = ++cnt;
ch[x][] = ch[x][] = rev[x] = ;
sz[x] = ; val[x] = w; fa[x] = f;
ch[f][kind] = cnt;
return x;
} void Build(int l, int r, int &x, int f, int kind)
{
if(l > r) return ;
int m = (l + r) >> ;
x = NewNode(num[m], f, kind);
Build(l, m - , ch[x][], x, );
Build(m + , r, ch[x][], x, );
PushUp(x);
} void Init()
{
root = cnt = tol = ;
rev[] = val[] = fa[] = sz[] = ch[][] = ch[][] = ;
root = NewNode(, , );
ch[root][] = NewNode(, root, );
sz[root] = ;
Build(, n, keytree, ch[root][], );
PushUp(ch[root][]); PushUp(root);
} void Rotate(int x, int kind)
{
int y = fa[x], z = fa[y];
PushDown(y); PushDown(x);
ch[y][!kind] = ch[x][kind];
if(ch[y][!kind]) fa[ch[y][!kind]] = y;
if(z) {
if(y == ch[z][]) ch[z][] = x;
else ch[z][] = x;
}
fa[x] = z; fa[y] = x;
ch[x][kind] = y;
PushUp(y);
} void Splay(int x, int goal)
{
while(fa[x] != goal) {
int y = fa[x], z = fa[y];
PushDown(z); PushDown(y); PushDown(x);
int kind1 = x == ch[y][];
int kind2 = y == ch[z][];
if(z == goal) {
Rotate(x, kind1);
} else {
if(kind1 == kind2) {
Rotate(y, kind1);
} else {
Rotate(x, kind1);
}
Rotate(x, kind2);
}
}
PushUp(x);
if(goal == ) root = x;
} void RTO(int k, int goal)
{
int x = root;
PushDown(x);
while(k != sz[lson] + ) {
if(k <= sz[lson]) x = lson;
else k -= sz[lson] + , x = rson;
PushDown(x);
}
Splay(x, goal);
} void Cut(int l, int r, int c)
{
RTO(l, );
// Debug();
RTO(r + , root);
int tmp = keytree;
keytree = ;
// Debug();
RTO(c + , );
// Debug();
RTO(c + , root);
fa[tmp] = ch[root][];
keytree = tmp;
} void Reverse(int l, int r)
{
RTO(l, ); RTO(r + , root);
rev[keytree] ^= ;
} void Down(int x)
{
PushDown(x);
if(lson) Down(lson);
if(rson) Down(rson);
} void Travel(int x)
{
if(lson) Travel(lson);
ans[tol++] = val[x];
if(rson) Travel(rson);
} void Debug()
{
Down(root);
Travel(root);
for(int i = ; i <= n; i++) {
if(i == n) printf("%d\n", ans[i]);
else printf("%d ", ans[i]);
}
}
}spy; int main()
{
int n, m;
while(scanf("%d%d", &n, &m)) {
if(n < || m < ) break;
spy.n = n;
for(int i = ; i <= n; i++) spy.num[i] = i;
spy.Init();
while(m--) {
char s[];
int a, b, c;
scanf("%s", s);
if(s[] == 'C') {
scanf("%d%d%d", &a, &b, &c);
spy.Cut(a, b, c);
} else {
scanf("%d%d", &a, &b);
spy.Reverse(a, b);
}
}
spy.Debug();
}
return ;
}

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

  1. HDU 3487 Play with Chain(Splay)

    题目大意 给一个数列,初始时为 1, 2, 3, ..., n,现在有两种共 m 个操作 操作1. CUT a b c 表示把数列中第 a 个到第 b 个从原数列中删除得到一个新数列,并将它添加到新数 ...

  2. HDU 5795:A Simple Nim(博弈)

    http://acm.hdu.edu.cn/showproblem.php?pid=5795 A Simple Nim Problem Description   Two players take t ...

  3. HDU 6188:Duizi and Shunzi(贪心)(广西邀请赛)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6188 题意 有n个数字,每个数字小于等于n,两个相同的数字价值为1,三个连续的数字价值为1 .问这n个 ...

  4. HDU 3183:A Magic Lamp(RMQ)

    http://acm.hdu.edu.cn/showproblem.php?pid=3183 题意:给出一个数,可以删除掉其中m个字符,要使得最后的数字最小,输出最后的数字(忽略前导零). 思路:设数 ...

  5. HDU 6011:Lotus and Characters(贪心)

    http://acm.hdu.edu.cn/showproblem.php?pid=6011 题意:共有n种字符,每种字符有一个val和一个cnt,代表这个字符的价值和数量.可以制造的总价值是:第一个 ...

  6. HDU 5968:异或密码(暴力)

    http://acm.hdu.edu.cn/showproblem.php?pid=5968 题意:中文题意. 思路:一开始不会做,后来发现数据范围很小,而且那个数要是连续的,所以可能把所有情况枚举出 ...

  7. HDU 2830:Matrix Swapping II(思维)

    http://acm.hdu.edu.cn/showproblem.php?pid=2830 题意:-- 思路:对于每一列,它是固定的,用dp[][]处理出连续的长度.例如: 假设我们扫第四列的时候, ...

  8. HDU 5113:Black And White(DFS)

    题目链接 题意 给出一个n*m的图,现在有k种颜色让你对这个图每个格子染色,每种颜色最多可以使用col[i]次,问是否存在一种染色方案使得相邻格子的颜色不同. 思路 以为是构造题,结果是爆搜.对于每一 ...

  9. HDU 1231:最大连续子序列(DP)

    pid=1231">最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav ...

随机推荐

  1. Hadoop学习笔记: sqoop配置与使用

    sqoop即SQL-to-Hadoop,是一个把数据从关系型数据库导入到Hadoop系统中的工具(HDFS,HIVE和HBase),也可以将数据从Hadoop导入到关系型数据库.本文以sqoop 1. ...

  2. ATS连接 https

    HTTPS协议是Http Over SSL,简单来说就是HTTP的安全版本,在HTTP的基础上增加SSL/TLS加密传输协议,通过HTTPS加密传输和身份认证保证了传输过程的安全性.在登录网银和电子邮 ...

  3. 使用NSURLSession请求需要AD认证的HTTPS服务器

    关键代码:使用后台下载PDF文件 - (void)startDownloadPDF{ NSURLSession *session = [self session]; NSString *downloa ...

  4. electron "Cannot find module 'dialog'", source: module.js (336)"

    打算用electron的dialog api 谁知道, 按官方api http://electron.atom.io/docs/v0.33.0/api/dialog/ https://github.c ...

  5. BeanUtils设置字段值失败问题

    package org.apache.commons.beanutils; import static org.junit.Assert.*; import java.beans.BeanInfo; ...

  6. 《30天自制操作系统》07_day_学习笔记

    harib04a: P126    获取按键编码: 让程序在按下键盘的键之后,将键值编码显示出来 修改的是前面编写的鼠标按键的处理键盘中断的函数inthandler21() 这里笔者介绍了怎样把中断号 ...

  7. SQL 数据库 函数

    1.数学函数:操作一个数据,返回一个结果 --取上限ceiling select code,name,ceiling(price) from car ; --取下限 floor select floo ...

  8. Winform TreeView 节点拖动

    private void treeView_ItemDrag(object sender, ItemDragEventArgs e) { TreeNode dragNode = e.Item as T ...

  9. 省市联动初探AJAX操作数据

    主要学习代码: List.html <script type="text/javascript"> function GetXhr() { return new XML ...

  10. [转] HashMap的工作原理

    HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此 ...