splay模版

#include <cstdio>
#include <queue>
#include <cstring>
using std::queue;
const int N = 100010;
struct node 
{
    node *c[2],*fa;
    int val;
    int sz;
    int belong;
    void setc(int d,node *s) {
        c[d]  = s;
        s->fa = this;
    }
    bool d() {
        return fa->c[1]==this;
    }
    void up(){
        sz = c[0]->sz + c[1]->sz + 1;
    }
    void clear(node *null) {
        sz = 1; 
        c[0] = c[1] = fa = null;
    }
}NODE[N],*null=NODE;
node* ID[N];
int top;
struct Tree
{
    node* root;
    void init(int v) {
        node* x = &NODE[++top];
        x->belong = top;
        x->val = v;
        x->clear(null);
        root = x;
    }
    void rot(node* x,int f) {
        node* y = x->fa;
        y->setc(!f,x->c[f]);
        x->fa = y->fa;
        if(y->fa!=null) y->fa->c[y->d()] = x;
        x->setc(f,y);
        y->up();
    }
    void splay(node *x,node *goal) {
        while(x->fa!=goal) {
            if(x->fa->fa == goal) rot(x,!x->d());
            else {
                 bool f = x->fa->d();
                 x->d() == f ? rot(x->fa,!f): rot(x,f);
                 rot(x,!f);
            }
        }
        x->up();
        if(goal == null) root = x;
    }
    void RTO(int k,node *goal) {
        node *x = root;
        while(x->c[0]->sz+1 != k) {
            if(x->c[0]->sz+1 > k) x = x->c[0];
            else {
                k -= x->c[0]->sz + 1;
                x = x->c[1];
            }
        }
        splay(x,goal);
    }
    void delRoot() {
        node* t = root;
        if(t->c[1]!=null) {
            root = t->c[1];
            RTO(1,null);
            root->setc(0,t->c[0]);
//            root->c[0] = t->c[0];
  //          if(root->c[0]!=null) root->c[0]->fa = root;
        } else root = root->c[0];
        root->fa = null;
        if(root!=null) root->up();
    }
    void change(node* x,int v){
        splay(x,null);
        delRoot();
        x->val = v; 
        x->clear(null);
        insert(root,x);
    }
    void insert(node* &x,node *y,node* fa=null) {// 如何减少对父亲指针的赋值
        if(x == null) {
            x = y;
            y->fa = fa;
            return ;
        }
        if(x->val >= y->val) insert(x->c[0],y,x);
        else insert(x->c[1],y,x);
        x->up();
    }
    int find(node *x,int k) {
        if(x->c[0]->sz + 1 == k) return x->val;
        else if(x->c[0]->sz + 1 > k) return find(x->c[0],k);
        else return find(x->c[1],k-x->c[0]->sz-1);
    }
    void debug(node *x) {
        printf("%d lc:%d rc:%d\n",x->val,x->c[0]->val,x->c[1]->val);
        if(x->c[0]!=null) debug(x->c[0]);
        if(x->c[1]!=null) debug(x->c[1]);
    }
}spt[N];

板二:

#include <iostream>
#include <cstdio>
#include <string.h>
#include <string>
#include <algorithm>
using namespace std;
const int maxn = 1000000 + 10;
const int inf = 1000000000;
struct Node
{
    int val, d;
    int sum, siz;
    int max, mls, mrs;
    Node * par, * ch[2];
    bool rev, sm;
};
Node * root, * null;
Node nod[maxn];
Node * Ind[maxn];
int tot;
int number[maxn], nc;
struct SplayTree
{
    Node * NewNode(int val, Node * par)
    {
        Node * x = Ind[tot++];
        x->val = x->sum = x->max = x->mls = x->mrs = val;
        x->siz = 1;
        x->par = par;
        x->rev = x->sm = false;
        if (x->ch[0] != null) Ind[--tot] = x->ch[0];
        if (x->ch[1] != null) Ind[--tot] = x->ch[1];
        x->ch[0] = x->ch[1] = null;
        return x;
    };
    void Modify(Node * x, int d)
    {
        if (x == null) return;
        x->val = x->d = d;
        x->sm = true;
        x->sum = x->siz * d;
        x->mls = x->mrs = x->max = max(x->sum, d);
        x->rev = false;
    };
    void Reverse(Node * x)
    {
        if (x == null) return;
        x->rev ^= true;
        swap(x->mls, x->mrs);
        swap(x->ch[0], x->ch[1]);
    }
    void PushDown(Node * x)
    {
        if (x == null) return;
        if (x->sm) {
            Modify(x->ch[0], x->d);
            Modify(x->ch[1], x->d);
            x->sm = false;
        }
        if (x->rev) {
            Reverse(x->ch[0]);
            Reverse(x->ch[1]);
            x->rev = false;
        }
    }
    void PushUp(Node * x)
    {
        if (x == null) return;
        x->siz = x->ch[0]->siz + x->ch[1]->siz + 1;
        x->sum = x->ch[0]->sum + x->ch[1]->sum + x->val;
        x->mls = max(x->ch[0]->mls, x->ch[0]->sum + x->val + max(0, x->ch[1]->mls));
        x->mrs = max(x->ch[1]->mrs, x->ch[1]->sum + x->val + max(0, x->ch[0]->mrs));
        x->max = max(x->ch[0]->max, x->ch[1]->max);
        x->max = max(x->max, max(x->ch[0]->mrs, 0) + x->val + max(x->ch[1]->mls, 0));
        return;
    }
    void Rotate(Node * x, int c)
    {
        Node * y = x->par;
        PushDown(y);
        PushDown(x);
        y->ch[!c] = x->ch[c];
        if (x->ch[c] != null) x->ch[c]->par = y;
        x->par = y->par;
        if (y->par != null) {
            if (y->par->ch[0] == y) y->par->ch[0] = x;
            else y->par->ch[1] = x;
        }
        x->ch[c] = y;
        y->par = x;
        PushUp(y);
        if (y == root) root = x;
    }
    void Splay(Node * x, Node * f)
    {
        Node * y, * z;
        for (PushDown(x); x->par != f; ) {
            y = x->par, z = y->par;
            if (z == f) {
                    if (y->ch[0] == x) Rotate(x, 1);
                    else Rotate(x, 0);
            } else {
                if (z->ch[0] == y) {
                    if (y->ch[0] == x) Rotate(y, 1), Rotate(x, 1);
                    else Rotate(x, 0), Rotate(x, 1);
                } else {
                    if (y->ch[0] == x) Rotate(x, 1), Rotate(x, 0);
                    else Rotate(y, 0), Rotate(x, 0);
                }
            }
        }
        PushUp(x);
    }
    void Select(int k, Node * f)
    {
        Node * cur = root;
        int temp;
        while (1) {
            PushDown(cur);
            temp = cur->ch[0]->siz;
            if (k == temp) break;
            if (k < temp) cur = cur->ch[0];
            else {
                k -= (temp+1);
                cur = cur->ch[1];
            }
        }
        Splay(cur, f);
    }
    Node * Build(int L, int R, Node * par)
    {
        
        if (L > R) return null;
        int mid = (L + R) / 2;
        Node * x = NewNode(number[mid], par);
        x->ch[0] = Build(L, mid - 1, x);
        x->ch[1] = Build(mid + 1, R, x);
        PushUp(x);
        return x;
    }
    void Insert(int pos, int L, int R)
    {
        Select(pos, null);
        Select(pos+1, root);
        root->ch[1]->ch[0] = Build(L, R, root->ch[1]);
        PushUp(root->ch[1]);
        Splay(root->ch[1]->ch[0], null);
    }
    Node * Delete(int L, int R)
    {
        Node * ret;
        Select(L - 1, null);
        Select(R + 1, root);
        ret = root->ch[1]->ch[0];
        root->ch[1]->ch[0] = null;
        PushUp(root->ch[1]);
        Splay(root->ch[1], null);
        return ret;
    }
    void Init()
    {
        null = &nod[0];
        null->siz = null->sum = 0;
        null->val = null->mls = null->mrs = null->max = -inf;
        tot = 1;
        for (int i = 0; i != maxn; i++) {
            Ind[i] = &nod[i];
            nod[i].ch[0] = nod[i].ch[1] = null;
        }            
    }
    void Modify(int L, int R, int d)
    {
        Select(L-1, null);
        Select(R+1, root);
        Modify(root->ch[1]->ch[0], d);
        Splay(root->ch[1]->ch[0], null);
    }
    void Reverse(int L, int R)
    {
        Select(L-1, null);
        Select(R+1, root);
        Reverse(root->ch[1]->ch[0]);
        Splay(root->ch[1]->ch[0], null);
    }
    int Sum(int L, int R)
    {
        Select(L-1, null);
        Select(R+1, root);
        return root->ch[1]->ch[0]->sum;
    }
    void Print()
    {
        Select(1, null);
        printf("%d", root->val);
        for (int i = 2; i <= root->siz - 2; i++) {
            Select(i, null);
            printf(" %d", root->val);
        }
        printf("\n");
    }
} spt;
int n, m, x, y, D, T, len, P;
char op[30];
Node * temp;
int main()
{
    //freopen("sequence.in", "r", stdin);
    //freopen("sequence.out", "w", stdout);
    char op[20];
    int Q, p, cc;
    Node * Left, * Right;
    while (scanf("%d%d", &n, &Q)!=EOF) {
        spt.Init();
        for (int i = 1; i <= n; i++) scanf("%d", number + i);
        root = Left = spt.NewNode(-inf, null);
        Right = spt.NewNode(-inf, Left);
        Left->sum = Right->sum = 0;
        Left->ch[1] = Right;
        Right->ch[0] = spt.Build(1, n, Right);
        spt.PushUp(Right);
        spt.PushUp(Left);
        //spt.PushUp(root);
        //spt.Print();
        while (Q--) {
            scanf("%s", op);
            if (op[0] == 'M' && op[2] == 'X') printf("%d\n", root->max);
            else {
                scanf("%d%d", &p, &nc);
                if (op[0] == 'I') {
                    for (int i = 1; i <= nc; i++) scanf("%d", number + i);
                    spt.Insert(p, 1, nc);
                } else 
                if (op[0] == 'D') {
                    Ind[--tot] = spt.Delete(p, p + nc - 1);                    
                } else 
                if (op[0] == 'R') {
                    spt.Reverse(p, p + nc - 1);
                } else
                if (op[0] == 'M') {
                    scanf("%d", &cc);
                    spt.Modify(p, p + nc - 1, cc);
                } else
                if (op[0] == 'G') {
                    printf("%d\n", spt.Sum(p, p + nc - 1));
                }
            }
            //spt.Print();
        }
    }
    return 0;
}


白书模版:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stdlib.h>
using namespace std;

#define N 20005  
struct Treap{  
	Treap *ch[2];  
	int r;          //数字越大,优先级越高  
	int v;          //值  
	int size;       //子树的节点数  
	Treap(int v):v(v) { ch[0]=ch[1]=NULL; r=rand(); size=1;}  
	bool operator < (const Treap& rhs) const{  
		return r < rhs.r;  
	}  
	int cmp(int x) const{  
		if(x == v)return -1;  
		return x < v ? 0 : 1;  
	}  
	void maintain(){  //以该点为根的子树节点数(包括自己)
		size = 1;  
		if(ch[0] != NULL) size += ch[0]->size;  
		if(ch[1] != NULL) size += ch[1]->size;  
	}  
};  
Treap* root[N];  
//d=0代表左旋,d=1代表右旋
void rotate(Treap* &o, int d){  
	Treap* k = o->ch[d^1]; o->ch[d^1] = k->ch[d]; k->ch[d] = o;  
	o->maintain(); k->maintain(); o = k;  
}  
//在以o为根的子树中插入键值x,修改o
void insert(Treap* &o, int x){  
	if(o == NULL)  o = new Treap(x);  
	else {  
		int d = (x < o->v ? 0 : 1);  //不要用cmp函数,因为可能会有相同的节点
		insert(o->ch[d], x);  
		if(o->ch[d] > o) rotate(o, d^1);  
	}  
	o->maintain();  
}  
//删除键值为x的节点
void remove(Treap* &o, int x){  
	int d = o->cmp(x);  
	if(d == -1){  
		Treap* u = o;  
		if(o->ch[0] != NULL && o->ch[1] != NULL){  
			int d2 = (o->ch[0] > o->ch[1] ? 1: 0);  
			rotate(o, d2); remove(o->ch[d2], x);  
		}  
		else {  
			if(o->ch[0] == NULL) o = o->ch[1]; else o = o->ch[0];;  
			delete u;  
		}  
	}  
	else remove(o->ch[d], x);  
	if(o != NULL) o->maintain();  
}  
//第k大的值
int kth(Treap* o, int k){  
	if(o == NULL || k<=0 || k> o->size) return 0;  
	int s = (o->ch[1] == NULL ? 0 : o->ch[1]->size);  
	if( k == s+1) return o->v;  
	else if(k <= s) return kth(o->ch[1], k);  
	else return kth(o->ch[0], k - s - 1);  
}  

void mergeto(Treap* &src, Treap* &dest){  
	if(src->ch[0] != NULL) mergeto(src->ch[0], dest);  
	if(src->ch[1] != NULL) mergeto(src->ch[1], dest);  
	insert(dest, src->v);  
	delete src;  
	src = NULL;  
}  

void removetree(Treap* &x){  
	if(x->ch[0] != NULL) removetree(x->ch[0]);  
	if(x->ch[1] != NULL) removetree(x->ch[1]);  
	delete x;  
	x = NULL;  
}  

void splay(Treap* &o, int k){
	int d = o->cmp(k);
	if(d == 1) k -= o->ch[0]->size + 1;
	if(d != 1) {
		Treap * p = o->ch[d];
		int d2 = p->cmp(k);
		int k2 = (d2 == 0 ? k : k- p->ch[0]->size + 1);
		if(d2 != 1) {
			splay(p->ch[d2], k2);
			if(d == d2) rotate(o, d^1); else rotate(o->ch[d], d);
		}
		rotate(o, d^1);
	}
}
//合并left和right。假定left的所有元素比right小。注意right可以是NULL,但left不可以
Treap* merge(Treap* left, Treap* right){
	splay(left, left->size);
	left->ch[1] = right;
	left->maintain();
	return left;
}
//把o的前k小节点放在left里,其他的放在right里。l<=k<= o->size。 当k=o->size 时,right=NULL
void split(Treap* o, int k, Treap* &left, Treap* &right){
	splay(o, k);
	left = o;
	right = o->ch[1];
	o->ch[1] = NULL;
	left->maintain();
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值