不算很慢= =也谈不上快
反正我觉得挺好记的…
第一个真正写完的模板= =啧啧啧
#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]);
}