zoukankan      html  css  js  c++  java
  • Splay 记录

    luogu 模板 P3391 【模板】文艺平衡树(Splay)。

    知识点:1.splay模板题,练习splay,rotate顺序:x变成z的儿子,x的一个儿子变为y的一个儿子(具体哪个看代码),y变为x的儿子。

        2.splay函数:如起码还需转两次,如最近两次旋转路径为直线,则先转x的父亲,再转x;如为折线,转两次x。

        3.insert函数:记得记录父亲节点,如果父亲存在还要让父亲连向被插入数x,记得新建节点,新建节点两个儿子设置为0,将siz数设为1。

    #include <bits/stdc++.h>
    using namespace std;
    int n,m;
    int cnt = 0;
    struct edge
    {
    	int ch[2];
    	int ff;
    	int siz;
    	int val;
    	int lazy;
    }t[200002];
    int rt = 0;
    void pushup(int x)
    {
    	//错误1:忘记加1(这个点本身),原为t[x].siz = t[t[x].ch[0]].siz + t[t[x].ch[1]].siz; 
    	t[x].siz = t[t[x].ch[0]].siz + t[t[x].ch[1]].siz + 1;
    }
    void pushdown(int x)
    {
        if(t[x].lazy)
        {
            t[t[x].ch[0]].lazy^=1;
            t[t[x].ch[1]].lazy^=1;
            t[x].lazy=0;
            swap(t[x].ch[0],t[x].ch[1]);
        }
    }
    void rotate(int x)
    {
    	int y = t[x].ff;
        int z = t[y].ff;
        int k = t[y].ch[1] == x;
        t[z].ch[t[z].ch[1] == y] = x;
        t[x].ff = z;
        t[y].ch[k] = t[x].ch[k^1];
        t[t[x].ch[k^1]].ff = y;
        t[x].ch[k^1] = y;
        t[y].ff = x;
        pushup(y);
        pushup(x);
    }
    void splay(int x,int goal)
    {
    	while(t[x].ff != goal)
    	{
    		int y = t[x].ff,z = t[y].ff;
    	    if(z != goal)
    	    	if((t[z].ch[1] == y)^(t[y].ch[1] == x))rotate(x);
    	     	else rotate(y);
    	     rotate(x);
    	}
    	if(goal == 0)rt = x;
    }
    void insert(int x)
    {
    	int u = rt,ff = 0;
    	while(u)
    	{
    		ff = u;
    		u = t[u].ch[t[u].val < x];
    	}
        u = ++cnt;
        if(ff)t[ff].ch[t[ff].val < x] = u;
        t[u].val = x;
        t[u].siz = 1;
        t[u].ff = ff;
        t[u].ch[0] = t[u].ch[1] = 0;
        splay(u,0);
    }
    int Kth(int k)
    {
    	int u = rt;
    	while(1)
    	{
    		//错误2:一开始把所有t[t[u].ch[0]].siz写成了t[u].siz,理解错误。 
    		pushdown(u); 
    		if(t[t[u].ch[0]].siz >= k)u = t[u].ch[0];
    		else if(t[t[u].ch[0]].siz + 1 == k)return u;
    		else k -= (t[t[u].ch[0]].siz + 1),u = t[u].ch[1];
    	}
    	
    }
    
    void work(int l,int r)
    {
    	int ls = Kth(l);
    	int rs = Kth(r + 2);
    	splay(ls,0);
    	splay(rs,ls);
    	t[t[t[rt].ch[1]].ch[0]].lazy ^= 1;
    }
    void print(int u)
    {
        pushdown(u);
        if(t[u].ch[0])print(t[u].ch[0]);
        if(t[u].val>1&&t[u].val<n+2)printf("%d ",t[u].val-1);
        if(t[u].ch[1])print(t[u].ch[1]);
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i = 1;i <= n + 2;i++)insert(i);//这里是因为要留出两个空节点,一头一尾,给1当前驱,给n当后继,而1变成2,2变成3.....n变成n + 1。 
    	int l,r;
        while(m--)
        {
        	scanf("%d%d",&l,&r);
        	work(l,r);
        }
        print(rt);
        return 0;
    }

  • 相关阅读:
    Java读写文本文件操作
    java常用的文件读写操作
    CentOS yum 源的配置与使用
    每天一个linux命令目录
    Linux的概念与体系
    linux ACL权限规划:getfacl,setfacl使用
    基于大数据的电影网站项目开发之HBase分布式安装(四)
    基于大数据的电影网站项目开发之阶段性总结(三)
    基于大数据的电影网站项目开发之Hadoop2.6.0伪分布式设置(二)
    基于大数据的电影网站项目开发之CentOS的安装(一)
  • 原文地址:https://www.cnblogs.com/xyj1/p/10416264.html
Copyright © 2011-2022 走看看