• Splay详解


    因为博主太懒,所以这篇博客咕了。

    【模板】普通平衡树(Splay)

    #include <bits/stdc++.h>
    using namespace std;
    
    const int _ = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    
    struct node {
    	int fa, ch[2];
    	int val, cnt, siz;
    } tr[_];
    int root, tot = 0, N;
    
    int alloc(int val, int fa) {
    	tr[++tot].fa = fa;
    	tr[tot].val = val;
    	tr[tot].siz = tr[tot].cnt = 1;
    	return tot;
    }
    
    inline void update(int x) {
    	tr[x].siz = tr[tr[x].ch[0]].siz + tr[tr[x].ch[1]].siz + tr[x].cnt;
    }
    
    inline int ident(int x) { return tr[tr[x].fa].ch[1] == x; }
    
    inline void connect(int x, int fa, int how) {
    	tr[x].fa = fa;
    	tr[fa].ch[how] = x;
    }
    
    void rotate(int x) {
    	int y = tr[x].fa, z = tr[y].fa;
    	if (y == root) root = x;
    	int yson = ident(x), zson = ident(y);
    	int k = tr[x].ch[yson ^ 1];
    	connect(k, y, yson);
    	connect(y, x, yson ^ 1);
    	connect(x, z, zson);
    	update(y), update(x);
    }
    
    void splay(int x, int to) {
    	while (tr[x].fa != to) {
    		int y = tr[x].fa, z = tr[y].fa;
    		if (tr[y].fa != to)
    			(tr[z].ch[0] == y) ^ (tr[y].ch[0] == x) ? rotate(x) : rotate(y);
    		rotate(x);
    	}
    	if (!to) root = x;
    }
    
    void insert(int x) {
    	int u = root;
    	if (!u) {
    		root = alloc(x, 0);
    		return;
    	}
    	while (1) {
    		++tr[u].siz;
    		if (tr[u].val == x) {
    			++tr[u].cnt;
    			splay(u, 0);
    			return;
    		}
    		int nxt = x > tr[u].val;
    		if (!tr[u].ch[nxt]) {
    			int p = alloc(x, u);
    			tr[u].ch[nxt] = p;
    			splay(p, 0);
    			return;
    		}
    		u = tr[u].ch[nxt];
    	}
    }
    
    int find(int val) {
    	int u = root;
    	while (1) {
    		if (tr[u].val == val) {
    			splay(u, 0);
    			return u;
    		}
    		int nxt = val > tr[u].val;
    		if (!tr[u].ch[nxt]) return 0;
    		u = tr[u].ch[nxt];
    	}
    }
    
    void remove(int x) {
    	int pos = find(x);
    	if (!pos) return;
    	if (tr[pos].cnt > 1) {
    		--tr[pos].cnt, --tr[pos].siz;
    		return;
    	}
    	if (!tr[pos].ch[0] && !tr[pos].ch[1]) root = 0;
    	else if (!tr[pos].ch[0]) {
    		root = tr[pos].ch[1];
    		tr[root].fa = 0;
    	} else {
    		int u = tr[pos].ch[0];
    		while (tr[u].ch[1]) u = tr[u].ch[1];
    		splay(u, root);
    		connect(tr[pos].ch[1], u, 1);
    		connect(u, 0, 1);
    		root = u;
    		update(u);
    	}
    }
    
    int getrank(int val) {
    	int pos = find(val);
    	return tr[tr[pos].ch[0]].siz + 1;
    }
    
    int kth(int x) {
    	int u = root;
    	while (1) {
    		int rest = tr[u].siz - tr[tr[u].ch[1]].siz;
    		if (x > tr[tr[u].ch[0]].siz && x <= rest) {
    			splay(u, 0);
    			return tr[u].val;
    		}
    		if (x < rest) u = tr[u].ch[0];
    		else x -= rest, u = tr[u].ch[1];
    	}
    }
    
    int getpre(int val) {
    	int u = root;
    	int ans = -INF;
    	while (u) {
    		if (tr[u].val < val && tr[u].val > ans) ans = tr[u].val;
    		if (val > tr[u].val) u = tr[u].ch[1];
    		else u = tr[u].ch[0];
    	}
    	return ans;
    }
    
    
    int getnxt(int val) {
    	int u = root;
    	int ans = INF;
    	while (u) {
    		if (tr[u].val > val && tr[u].val < ans) ans = tr[u].val;
    		if (val >= tr[u].val) u = tr[u].ch[1];
    		else u = tr[u].ch[0];
    	}
    	return ans;
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("splay.in", "r", stdin);
    	freopen("splay.out", "w", stdout);
    #endif
    	scanf("%d", &N);
    	while (N--) {
    		int op, x;
    		scanf("%d%d", &op, &x);
    		if (op == 1) insert(x);
    		else if (op == 2) remove(x);
    		else if (op == 3) printf("%d
    ", getrank(x));
    		else if (op == 4) printf("%d
    ", kth(x));
    		else if (op == 5) printf("%d
    ", getpre(x));
    		else if (op == 6) printf("%d
    ", getnxt(x));
    	}
    	return 0;
    }
    

    【模板】文艺平衡树(Splay区间修改)

    #include <bits/stdc++.h>
    using namespace std;
    
    inline int ty() {
    	char ch = getchar(); int x = 0, f = 1;
    	while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    	return x * f;
    }
    
    const int _ = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    
    struct node {
    	int fa, ch[2];
    	int val, cnt, siz, tag;
    } tr[_];
    int root = 1, tot = 0, N, M, num[_];
    
    inline void update(int x) {
    	tr[x].siz = tr[tr[x].ch[0]].siz + tr[tr[x].ch[1]].siz + tr[x].cnt;
    }
    
    inline int ident(int x) { return tr[tr[x].fa].ch[1] == x; }
    
    inline void connect(int x, int fa, int how) {
    	tr[x].fa = fa;
    	tr[fa].ch[how] = x;
    }
    
    inline void pushdown(int x) {
    	if (x && tr[x].tag) {
    		tr[tr[x].ch[0]].tag ^= 1;
    		tr[tr[x].ch[1]].tag ^= 1;
    		swap(tr[x].ch[0], tr[x].ch[1]);
    		tr[x].tag = 0;
    	}
    }
    
    int build(int l, int r, int fa) {
    	if (l > r) return 0;
    	int mid = (l + r) >> 1;
    	int cur = ++tot;
    	tr[cur].fa = fa;
    	tr[cur].val = num[mid];
    	++tr[cur].cnt, ++tr[cur].siz;
    	tr[cur].tag = 0;
    	tr[cur].ch[0] = build(l, mid - 1, cur);
    	tr[cur].ch[1] = build(mid + 1, r, cur);
    	update(cur);
    	return cur;
    }
    
    void rotate(int x) {
    	int y = tr[x].fa, z = tr[y].fa;
    	if (y == root) root = x;
    	int yson = ident(x), zson = ident(y);
    	int k = tr[x].ch[yson ^ 1];
    	connect(k, y, yson);
    	connect(y, x, yson ^ 1);
    	connect(x, z, zson);
    	update(y), update(x);
    }
    
    void splay(int x, int to) {
    	while (tr[x].fa != to) {
    		int y = tr[x].fa, z = tr[y].fa;
    		if (tr[y].fa != to)
    			(tr[z].ch[0] == y) ^ (tr[y].ch[0] == x) ? rotate(x) : rotate(y);
    		rotate(x);
    	}
    	if (!to) root = x;
    }
    
    int find(int x) {
    	int u = root;
    	while (1) {
    		pushdown(u);
    		int rest = tr[u].siz - tr[tr[u].ch[1]].siz;
    		if (x > tr[tr[u].ch[0]].siz && x <= rest) {
    			splay(u, 0);
    			return u;
    		}
    		if (x < rest) u = tr[u].ch[0];
    		else x -= rest, u = tr[u].ch[1];
    	}
    }
    
    void rever(int l, int r) {
    	l = find(l - 1), r = find(r + 1);
    	splay(l, 0);
    	splay(r, l);
    	int pos = tr[root].ch[1];
    	pos = tr[pos].ch[0];
    	tr[pos].tag ^= 1;
    }
    
    void dfs(int x) {
    	pushdown(x);
    	if (tr[x].ch[0]) dfs(tr[x].ch[0]);
    	if (tr[x].val != INF && tr[x].val != -INF) printf("%d ", tr[x].val);
    	if (tr[x].ch[1]) dfs(tr[x].ch[1]);
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("splay.in", "r", stdin);
    	freopen("splay.out", "w", stdout);
    #endif
    	N = ty(), M = ty();
    	num[1] = -INF, num[N + 2] = INF;
    	for (int i = 1; i <= N; ++i) num[i + 1] = i;
    	build(1, N + 2, 0);
    	while (M--) {
    		int l = ty(), r = ty();
    		rever(l + 1, r + 1);
    	}
    	dfs(root);
    	return 0;
    }
    
    既然选择了远方,便只顾风雨兼程。
  • 相关阅读:
    MAXSCRIPT 连数据库(转)
    Docker安装部署ELK教程 (Elasticsearch+Kibana+Logstash+Filebeat)
    ArrayList知识点
    HashMap知识点
    使用docker 安装nacos
    记录docker 安装sonarqube和安装的一些坑
    sql优化
    Centos7下安装Docker
    使用docker安装gitlab
    docker安装jenkins
  • 原文地址:https://www.cnblogs.com/newbielyx/p/12112192.html
Copyright © 2020-2023  润新知