HDU3487 Play With Chains(Splay)

很裸的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)

时间: 2024-11-10 13:09:22

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

HDU3487 Play With Chain [Splay]

题目传送门 题目描述 Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamonds on it. Diamonds are numbered from 1 to n.At first, the diamonds on the chain is a sequence: 1, 2, 3, …, n.He will perform two types of operation

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

Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamonds on it. Diamonds are numbered from 1 to n.At first, the diamonds on the chain is a sequence: 1, 2, 3, …, n.He will perform two types of operations:CUT a b c

HDU3487(splay区间翻转+区间切割)

题意:开始有一个1,2,3,...n的序列,进行m次操作,cut a b c将区间[a,b]取出得到新序列,将区间插入到新序列第c个元素之后.filp a b 将区间a,b翻转,输出最终的序列. 思路:对于cut操作我们需要先提取出区间[a,b]然后,先暂时分裂出去,然后以c为边界分裂左右两部分,然后合并左边的和区间[a,b],将最大的旋转至根,然后和右边的合并.对于filp操作,我们可以使用lazy标记,先不翻转,需要的时候再翻转,代码如下 [cpp] view plaincopy /****

HDU 3487(Play with Chain-Splay)[template:Splay]

Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4679    Accepted Submission(s): 1892 Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamon

HDU 3487 Splay tree

Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6779    Accepted Submission(s): 2678 Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamond

HDU 3487 splay区间翻转切割

Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3986    Accepted Submission(s): 1633 Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamon

Splay树——HDU 3487 Play with Chain

对应HDU题目:点击打开链接 Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4571    Accepted Submission(s): 1859 Problem Description YaoYao is fond of playing his chains. He has a chain cont

BZOJ 1861 [Zjoi2006]Book 书架 ——Splay

[题目分析] 模板题目. 首尾两个虚拟结点,十分方便操作. [代码] #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <map> #include <set> #include <queue> #include <string> #include <iostream> #include

及其简短的Splay代码

#include <stdio.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <math.h> #include <iostream> #define inf 1000000000 using namespace std; #define getch() getchar() inline int F() {register int aa ,