zoukankan      html  css  js  c++  java
  • 【模板】文艺平衡树

    题目

    (m) 次区间翻转操作,(1 leq n,m leq 100000)

    分析

    平衡树模板
    于是放上 (fhq-treap) 的板子

    (Code)

    #include<cstdio>
    #include<algorithm>
    #include<ctime>
    using namespace std;
    
    const int N = 1e5 + 5;
    int n, m, rt;
    
    struct node{
    	int ls, rs, val, rnd, tag, siz;
    }tr[N];
    
    void read(int &x)
    {
    	x = 0; char ch = getchar();
    	while (ch < '0' || ch > '9') ch = getchar();
    	while (ch >= '0' && ch <= '9')
    		x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    }
    
    void update(int p){tr[p].siz = tr[tr[p].ls].siz + tr[tr[p].rs].siz + 1;}
    
    int new_node(int v)
    {
    	static int tot = 0;
    	tr[++tot] = node{0, 0, v, rand(), 0, 1};
    	return tot;
    }
    
    int build(int l, int r)
    {
    	if (l > r) return 0; 
    	int mid = (l + r) >> 1, p = new_node(mid);
    	tr[p].ls = build(l, mid - 1);
    	tr[p].rs = build(mid + 1, r);
    	update(p); return p;
    }
    
    void pushdown(int p)
    {
    	if (!p || !tr[p].tag) return;
    	tr[p].tag = 0;
    	swap(tr[p].ls, tr[p].rs);
    	if (tr[p].ls) tr[tr[p].ls].tag ^= 1;
    	if (tr[p].rs) tr[tr[p].rs].tag ^= 1;
    }
    
    void split(int p, int k, int &x, int &y)
    {
    	if (!p) x = y = 0;
    	else{
    		pushdown(p);
    		if (k <= tr[tr[p].ls].siz)
    			y = p, split(tr[p].ls, k, x, tr[p].ls);
    		else x = p, split(tr[p].rs, k - tr[tr[p].ls].siz - 1, tr[p].rs, y);
    		update(p);
    	}
    }
    
    int merge(int x, int y)
    {
    	if (!x || !y) return x + y;
    	pushdown(x), pushdown(y);
    	if (tr[x].rnd < tr[y].rnd)
    	{
    		tr[x].rs = merge(tr[x].rs, y);
    		update(x); return x;
    	}
    	else{
    		tr[y].ls = merge(x, tr[y].ls);
    		update(y); return y;
    	}
    }
    
    void dfs(int p)
    {
    	if (!p) return;
    	pushdown(p); 
    	dfs(tr[p].ls); 
    	printf("%d ", tr[p].val);
    	dfs(tr[p].rs);
    }
    
    void reverse(int l, int r)
    {
    	int a, b, c, d;
    	split(rt, r, a, b), split(a, l - 1, c, d);
    	tr[d].tag ^= 1 , rt = merge(merge(c, d), b);
    }
    
    int main()
    {
    	srand(time(0));
    	read(n), read(m);
    	rt = build(1, n);
    	for(register int i = 1, l, r; i <= m; i++)
    		read(l), read(r), reverse(l, r);
    	dfs(rt);
    }
    
  • 相关阅读:
    shell 脚本3 (输出与流程控制)
    centos 添加sudo 权限
    rz安装
    centos 安装mysql
    linux删除文件未释放
    关于字符串String的编程。
    spring mvc 学习指南二
    spring mvc 学习指南一
    《 spring mvc 》学习计划
    关于jsp的总结
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/14060658.html
Copyright © 2011-2022 走看看