块状链表
luckydrawbox · · 个人记录
使用前,请根据自己需要更改基本数据类型:
#define B_L_T int
以上实现了一个以
为了实现输出元素值的操作,使用前请根据需要更改输出方式
void put(B_L_T val){
printf("%d ",val);
}
变量
使用前要设定好
已经实现的操作
可用于扩展的基本操作
块状链表灵活多变,可以使用以下基本操作扩展到其他操作。
#define B_L_T int
struct Block_List{
int tot,nc[N],size,len;
double max_len;
struct Block{
int head,next;
int len;
B_L_T b[2*N];
}a[N],e;
B_L_T add[M];
Block_List(){
tot=0;size=0;
e.head=e.next=0;
e.len=0;
max_len=2;
for(int i=1;i<N;i++)
nc[i]=i;
}
int build(int p){
int np=nc[++tot];
a[np]=e;
a[np].head=p;
a[np].next=a[p].next;
a[a[p].next].head=np;
a[p].next=np;
return np;
}
void del(int p){
nc[tot--]=p;
a[a[p].head].next=a[p].next;
a[a[p].next].head=a[p].head;
}
int get(int &p){
int kp=a[0].next;
for(;kp;kp=a[kp].next)
if(a[kp].len<p)
p-=a[kp].len;
else
break;
p--;
return kp;
}
void split(int p,int pos){
int np=build(p);
a[np].len=pos;
a[p].len-=a[np].len;
for(int i=0;i<a[np].len;i++)
a[np].b[i]=a[p].b[i+a[p].len];
}
void merge(int p){
for(int i=0;i<a[a[p].next].len;i++)
a[p].b[a[p].len+i]=a[a[p].next].b[i];
a[p].len+=a[a[p].next].len;
del(a[p].next);
}
void insert(int p,int n){
n--;
if(p>size)
return;
size+=n+1;
len=sqrt(size);
int kp=get(p),nkp;
if(p^(a[kp].len-1))
split(kp,p);
nkp=kp;
for(int i=0;i<n/len;i++){
nkp=build(nkp);
a[nkp].len=len;
for(int j=0;j<a[nkp].len;j++)
a[nkp].b[j]=add[j+i*len];
}
nkp=build(nkp);
a[nkp].len=n-n/len*len+1;
for(int i=n/len*len;i<=n;i++)
a[nkp].b[i-n/len*len]=add[i];
for(;nkp&&(!kp||nkp!=a[kp].head);nkp=a[nkp].head){
if(a[nkp].next&&a[nkp].len+a[a[nkp].next].len<max_len*len)
merge(nkp);
}
}
void remove(int p,int n){
if(p>size)
return;
int l=p,r=min(p+n-1,size);
size-=r-l+1;
len=sqrt(size);
int kl=get(l),kr=get(r);
if(l){
split(kl,l-1);
kl=a[kl].next;
}
if(r^(a[kr].len-1))
split(kr,r);
for(int k=kl;k^a[kr].next;k=a[k].next)
del(k);
if(a[kl].head&&a[kr].next&&a[a[kl].head].len+a[a[kr].next].len<max_len*len)
merge(a[kl].head);
}
void put(B_L_T val){
printf("%d ",val);
}
void write(int l,int r){
int lsl=l,lsr=r;
int kl=get(l),kr=get(r);
if(kl==kr){
for(int i=l;i<=r;i++)
put(a[kl].b[i]);
return;
}
write(lsl,lsl+a[kl].len-1-l);
for(int k=a[kl].next;k^kr;k=a[k].next)
for(int i=0;i<a[k].len;i++)
put(a[k].b[i]);
write(lsr-r,lsr);
}
}K;