很裸的Splay,抄一下CLJ的模板当作复习,debug了一个下午,收获是终于搞懂了以前看这个模板里不懂的内容。以前用这个模板的时候没有看懂为什么get函数返回的前缀要加个引用,经过一下午的debug终于明白,如果加了引用的时候是会被修改到的,删除实际上就是将root->ch[1]->ch[0]置为null,但由于我们还要把这一段插回去,所以get的时候的t前面没有加引用,否则一旦置为null的话 t也会变为null。还有就是这次是第一次用这个模板进行插入,本题倒腾了很久就是在这个插入上,没有找到合适的姿势。经过摸索一个正确的姿势是在  1 2 3 4 5 ... n 的第k个位置后插入,应该是先get(k+1,k+1),然后直接在root->ch[1]里设置左儿子即可。复习Splay是为了学习LCT做准备吧。。- -0

#pragma warning(disable:4996)
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <map>
using namespace std; #define ll long long
#define maxn 350000 struct Node
{
Node *ch[2], *p;
int size,val;
int rev;
Node(){ size = 0; val = 0; rev = 0; }
bool d(){
return this == p->ch[1];
}
void setc(Node *c, int d){
ch[d] = c; c->p = this;
}
void relax();
void revIt()
{
rev ^= 1;
}
void upd(){
size = ch[0]->size + ch[1]->size + 1;
}
}Tnull,*null=&Tnull; Node mem[maxn], *C = mem; void Node::relax()
{
if (rev){
swap(ch[0], ch[1]);
for (int i = 0; i < 2; i++){
if (ch[i] != null) ch[i]->revIt();
}
rev = 0;
}
} Node *make(int v)
{
C->ch[0] = C->ch[1] = null;
C->size = 1; C->val = v; C->rev = 0;
return C++;
} Node* build(int l, int r)
{
if (l >= r) return null;
int m = (l + r) >> 1;
Node *t = make(m);
t->setc(build(l, m), 0);
t->setc(build(m + 1, r), 1);
t->upd();
return t;
} Node *root; void rot(Node *t)
{
Node *p = t->p;
p->relax();
t->relax();
int d = t->d();
p->p->setc(t, p->d());
p->setc(t->ch[!d], d);
t->setc(p, !d);
p->upd();
if (p == root) root = t;
} void splay(Node *t, Node *f = null)
{
while (t->p != f){
if (t->p->p == f) rot(t);
else t->d() == t->p->d() ? (rot(t->p), rot(t)) : (rot(t), rot(t));
}
t->upd();
} Node* select(int k) {
for (Node*t = root;;) {
t->relax();
int c = t->ch[0]->size;
if (k == c)
return t;
if (k > c)
k -= c + 1, t = t->ch[1];
else
t = t->ch[0];
}
} Node*&get(int l, int r) { //[l,r)
Node*L = select(l - 1);
Node*R = select(r);
splay(L);
splay(R, L);
return R->ch[0];
} int n, m; int main()
{
while (cin >> n >> m)
{
if (n <0 && m <0) break;
memset(mem, 0, sizeof(mem));
C = mem;
root = build(0, n + 2); root->p = null;
char oper[10];
int li, ri, wi;
for (int i = 0; i < m; i++){
scanf("%s", oper);
if (oper[0] == 'C'){
scanf("%d%d%d", &li, &ri, &wi);
Node *t = get(li, ri + 1);
root->ch[1]->ch[0] = null;
splay(root->ch[1]);
Node *&x = get(wi+1, wi+1);
root->ch[1]->setc(t, 0);
}
else{
scanf("%d%d", &li, &ri);
Node *&t = get(li, ri + 1);
t->revIt();
splay(t);
}
}
for (int i = 1; i <= n; i++){
if (i >= 2) printf(" ");
Node *&t = get(i, i + 1);
printf("%d", t->val);
}
puts("");
}
return 0;
}

HDU3487 Play With Chains(Splay)的更多相关文章

  1. HDU--3487 Play with Chain (Splay伸展树)

    Play with Chain Problem Description YaoYao is fond of playing his chains. He has a chain containing ...

  2. HDU3487 Play With Chain [Splay]

    题目传送门 题目描述 Problem Description YaoYao is fond of playing his chains. He has a chain containing n dia ...

  3. HDU3487 Play with Chain splay 区间反转

    HDU3487 splay最核心的功能是将平衡树中的节点旋转到他的某个祖先的位置,并且维持平衡树的性质不变. 两个操作(数组实现) cut l,r, c把[l,r]剪下来放到剩下序列中第c个后面的位置 ...

  4. HDU-3487 Play with Chain Splay tee区间反转,移动

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3487 对于一个数列有两种操作:1.CUT a b c,先取出a-b区间的数,然后把它们放在取出后的第c ...

  5. hdu3487 splay树

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

  6. 【HDU3487】【splay分裂合并】Play with Chain

    Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamonds on it ...

  7. Hdu-3487 Splay树,删除,添加,Lazy延迟标记操作

    HDU_3487 题意:给出n和q,n代表1-n的序列,接下来q有两种操作,Cut a b c:表示把区间[a,b]截掉然后放在第c个数的后面,Flip a b 表示把区间[a,b]反转,经过一系列的 ...

  8. HDU 3487 Play with Chain | Splay

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

  9. 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 ...

随机推荐

  1. AppCan移动平台,开发者是这样用的……

    随着生活节奏的加快,每天各种压力山大,难免产生心理问题.然而穷的都要吃土了,又不想面对陌生人,怎么办? 近日,AppCan开发者樊星阳“一夜爆红”,引起猎云网的持续关注.起因是这样的,樊星阳利用App ...

  2. 掌握这两个技术点,你可以玩转AppCan前端开发

    “AppCan的前端开发其实非常简单,只要掌握两方面的技术即可.一方面是会使用栅格布局完成UI的界面排版,另外一方面就是使用AppCan MVVM模型来完成整个页面构造和用户操作逻辑.” 在2016A ...

  3. ios中怎么样自动剪切图片周围超出的部分

    UIImageView *image = [[UIImageView alloc] init]; image.clipsToBounds = YES;

  4. Python: 迭代器与生成器小结

    迭代器与生成器的区别: 1. 迭代器由Class对象创建. 生成器由包含yield表达的Function对象或者Generator Expression创建. 2. 迭代器的原理: (1)由Itera ...

  5. 在meteor中如何使用ionic组件tabs,及如何添加使用cordova plugin inappbrower

    更新框架: meteor update meteor框架的优点不言而喻,它大大减轻了App前后端开发的负担,今年5月又获得B轮2000万融资,代表了市场对它一个免费.开源开发框架的肯定.cordova ...

  6. python 安装scrapy

    1. 首先你先得安装PYTHON...还是推荐2.7吧,之前装了3.3似乎和这个世界格格不入...先装个2.7. 并将python加入系统的环境变量. 2. 去scrapy 官网下载最新版本的scra ...

  7. FPGA入门1

    FPGA入门知识介绍    近几年来,由于现场可编程门阵列(FPGA)的使用非常灵活,又可以无限次的编程,已受到越来越多的电子编程者的喜爱,很多朋友都想学习一些FPGA入门知识准备进行这个行业,现在关 ...

  8. PB中获取datawindow提交的sql语句

    PB的群里边,有人问的到这个问题,查了一下,综合了两条回答,得到了答案 1.DW 控件的SQLpreview 事件里的sqlsyntax 参数即是 2.pb一般使用占位符优化SQL语句,也就是你看到的 ...

  9. 基于PBOC电子钱包的圈存过程详解

    基于pboc的电子钱包的圈存过程,供智能卡行业的开发人员参考 一. 圈存 首先终端和卡片有一个共同的密钥叫做圈存密钥:LoadKey   (Load即圈存的意思,unLoad,是圈提的意思) 假设Lo ...

  10. java 图片处理

    /* * 图片处理类 */ package image; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.j ...