Splay模板 初步修改完成

不算很慢= =也谈不上快
反正我觉得挺好记的…

第一个真正写完的模板= =啧啧啧

#include<iostream>
#include<stdio.h>
#include<string.h>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=500005;
int n,m,r,c,pos,tot,temp;
int val[maxn],fa[maxn],ch[maxn][2];
int s[maxn],z[maxn];
bool ischild(int x)
{
    return ch[fa[x]][1]==x;
}
void link(int x,int y,int d)
{
    if(y)ch[y][d]=x;
    if(x)fa[x]=y;
}
void maintain(int x)
{
    int lson=ch[x][0],rson=ch[x][1];
    s[x]=s[lson]+s[rson]+z[x];
    //其它
}
void pushdown(int x)
{
    int lson=ch[x][0],rson=ch[x][1];
    //标记下传
}
void rotate(int x)
{
    int d=ischild(x);
    int y=fa[x];
    if(y==r)r=x;
    link(x,fa[y],ischild(y));
    link(ch[x][!d],y,d);
    link(y,x,!d);
    maintain(y);
}
void Splay(int x,int goal=0)
{
    int y=fa[x],z=fa[y];
    while(y!=goal)
    {
        pushdown(z);
        pushdown(y);
        pushdown(x);
        if(z==goal)
        {
            rotate(x);
            break;
        }
        if(ischild(x)^ischild(y))rotate(x);
        else rotate(y);
        rotate(x);
        y=fa[x],z=fa[y];
    }
    maintain(x);
}
int getnext(int x)
{
    x=ch[x][1];
    while(ch[x][0])x=ch[x][0];
    return x;
}
int getpre(int x)
{
    x=ch[x][0];
    while(ch[x][1])x=ch[x][1];
    return x;
}
int getkth(int k)
{
    int x=r;
    while(x)
    {
        pushdown(x);
        if(s[ch[x][1]]>=k)x=ch[x][1];
        else if(s[ch[x][1]]+z[x]>=k)return x;
        else x=ch[x][0],k-=s[ch[x][1]]+z[x];
    }
    return x;
}
int getval(int k)//返回最靠近k的val值【可用于插入节点
{
    int x=r;
    while(x)
    {
        pushdown(x);
        if(val[x]==k)return x;
        if(ch[x][val[x]<k])x=ch[x][val[x]<k];
        else return x;
    }
    return x;
}
int newnode(int v)
{
    int x=++tot;
    fa[x]=ch[x][0]=ch[x][1]=0;
    s[x]=z[x]=1;
    val[x]=v;
    //标记初始化
    return x;
}
void addtree(int k)
{
    if(!r)
    {
        r=newnode(k);
        return;
    }
    int x=getval(k);
    if(val[x]==k)z[x]++;
    else link(newnode(k),x,val[x]<k);
    Splay(x);
}
void erase(int x)
{
    if(!x)return;
    //回收内存的话需要增加递归内存回收机制
}
void deltree(int pos,int tot)
{
    Splay(getkth(pos));
    Splay(getkth(pos+tot+1),r);//最常用的区间处理方式,包括标记、删除、求和等等
    int x=ch[r][1];x=ch[x][0];ch[ch[r][1]][0]=0;
    erase(x);
    Splay(ch[r][1]);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值