• 「题解」:[splay]普通平衡树(死亡调试)


    普通平衡树,模板的不能再模板的模板题。我调了两个小时。。。

    早先看yyb大神的blog学习splay,看的风生水起然而没有发现,大神的坑没有填……没有rank操作和k_th操作。

    只能自己摸索,问问大佬

    yzh巨佬拨冗花了五分钟给我解释清楚了k_th和rank求得东西是不去重的(用拙劣的语言表达大神高超的技巧,诸位勿喷)并且给我讲明白了size的各种操作以及妙用后我就再也不会把cnt和size写混了,就回去自己写。

    和同桌lyl大佬一起写完,一起T10……然后lyl大佬果断在平衡树中插入了inf和-inf(#define inf 0x7fffffff),A掉了,直降7000毫。

    蒟蒻颓了lyl大佬的想法也加了这么个东西,顺手改了一下k_th的求法,W20绝望。

    因为和lyl大佬看的同一份模板,我们对了一下各个函数,发现写的一毛一样。绝望+1。

    去找调代码专家ooo巨佬对了一遍,完全一样。绝望+999。

    最后找到了动动神佬,动动神佬花了三分钟找到了错误:查前驱的时候一个变量名写错了…… /一脸复杂 /生无可恋 /死掉算了

    罚自己默写三遍splay模板

    代码如下

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define read(a) a=init()
    using namespace std;
    struct node{
    	long long fa,ch[2],data,size,cnt;
    }t[10000003];
    long long n,root=0,tot=0,lei,thi;
    inline long long init()
    {
    	long long a=0,b=1;char ch=getchar();
    	while(ch>'9'||ch<'0'){if(ch=='-')b=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+(ch-'0');ch=getchar();}
    	return a*b;
    }
    inline void rotate(long long x)
    {
    	long long y=t[x].fa;
    	long long z=t[y].fa;
    	long long k=t[y].ch[1]==x;
    	t[z].ch[t[z].ch[1]==y]=x;
    	t[x].fa=z;
    	t[y].ch[k]=t[x].ch[k^1];
    	t[t[x].ch[k^1]].fa=y;
    	t[x].ch[k^1]=y;
    	t[y].fa=x;
    	t[y].size=t[t[y].ch[0]].size+t[t[y].ch[1]].size+t[y].cnt;
    	t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+t[x].cnt;
    }
    inline void splay(long long x,long long goal)
    {
    	while(t[x].fa!=goal)
    	{
    		long long y=t[x].fa,z=t[y].fa;
    		if(z!=goal)
    			(t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
    		rotate(x);
    	}
    	if(!goal)root=x;
    }
    inline void insert(long long x)
    {
    	long long u=root;
    	long long ff=0;
    	while(u&&x!=t[u].data)
    	{
    		ff=u;
    		u=t[u].ch[x>t[u].data];
    	}
    	if(u)
    		t[u].cnt++;
    	else
    	{
    		u=++tot;
    		if(ff)t[ff].ch[x>t[ff].data]=u;
    		t[u].fa=ff;
    		t[u].ch[0]=t[u].ch[1]=0;
    		t[u].size=1;
    		t[u].data=x;
    		t[u].cnt=1;
    	}
    	splay(u,0);
    }
    inline void find(long long x)
    {
    	long long u=root;
    	if(!u)return ;
    	while(t[u].ch[x>t[u].data]&&x!=t[u].data)
    		u=t[u].ch[x>t[u].data];
    	splay(u,0);
    }
    inline long long nxt(long long x,long long f)
    {
    	find(x);
    	long long u=root;
    	if(t[u].data>x&&f)return u;
    	if(t[u].data<x&&!f)return u;
    	u=t[u].ch[f];
    	while(t[u].ch[f^1])u=t[u].ch[f^1];
    	return u;
    }
    inline void delet(long long x)
    {
    	long long last=nxt(x,0);
    	long long next=nxt(x,1);
    	splay(last,0);
    	splay(next,last);
    	long long del=t[next].ch[0];
    	if(t[del].cnt>1)
    	{
    		t[del].cnt--;
    		splay(del,0);
    	}
    	else t[next].ch[0]=0;
    }
    inline long long rnk(long long x)
    {
    	find(x);
    	return t[t[root].ch[0]].size;
    }
    inline long long k_th(long long x)
    {
    	long long u=root;
    	if(t[u].size<x)return 0;
    	while(1)
    	{
    		int y=t[u].ch[0];
    		if(x>t[y].size+t[u].cnt)
    		{
    			x-=t[y].size+t[u].cnt;
    			u=t[u].ch[1];
    		}
    		else
    			if(t[y].size>=x)u=y;
    			else return t[u].data;
    	}
    }
    int main()
    {
    	read(n);
    	insert(0x7fffffff);
    	insert(-0x7fffffff);
    	for(register long long i=1;i<=n;++i)
    	{
    		read(lei),read(thi);
    		switch(lei)
    		{
    			case 1:{
    				insert(thi);
    				break;
    			}
    			case 2:{
    				delet(thi);
    				break;
    			}
    			case 3:{
    				printf("%lld
    ",rnk(thi));
    				break;
    			}
    			case 4:{
    				printf("%lld
    ",k_th(thi+1));
    				break;
    			}
    			case 5:{
    				printf("%lld
    ",t[nxt(thi,0)].data);
    				break;
    			}
    			case 6:{
    				printf("%lld
    ",t[nxt(thi,1)].data);
    				break;
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    常用sql(转)
    dos
    VS调试 DataTable (转载)
    JS 对象 数组求并集,交集和差集
    js跳出循环的方法区别(break,continue,return)(转载)
    echarts 曲线平滑配置
    js 动态 批量 创建局部或全局变量 (转载)
    电脑 闪屏 无法启动的原因
    js switch case 判断的是绝对相对===,值和类型都要相等
    无法创建“匿名类型”类型的常量值。此上下文仅支持基元类型或枚举类型。
  • 原文地址:https://www.cnblogs.com/xingmi-weiyouni/p/11017332.html
Copyright © 2020-2023  润新知