zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    LR杂记-nmon+analyser监控linux系统资源
    accept函数
    android performClick使用
    #line 的作用是改变当前行数和文件名称
    C++常用排序法、随机数
    C语言运算符优先级及结合性
    如何高效把一字节的位对换, bit0和bit7,bit1和bit6,以此类推.
    NumPy
    Rational Rose、PowerDesign、Visio的一些比较
    vld,Bounds Checker,memwatch,mtrace,valgrind,debug_new几种内存泄露检测工具的比较,Valgrind Cheatsheet
  • 原文地址:https://www.cnblogs.com/chanme/p/3833870.html
Copyright © 2011-2022 走看看