跳表求调
查看原帖
跳表求调
1041071
ltz761222楼主2025/1/12 22:32

真的有人会跳表吗……

//
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=1e5+10,L=15;
const double P=0.25;
struct skiplist{
	int x,ne,l;
}sk[N*L];int skq[N],skp;
int n;
inline void read(int& o)
{
	o=0;char c=0;bool g=false;
	while (c<'0' or c>'9')
		g=(c=='-'),c=getchar();
	while (c>='0' and c<='9')
		o=o*10+c-'0',c=getchar();
	o=(!g)?o:-o;
}
inline void build(int dx)
{
	for (int i=1;i<=L;i++)
		sk[++skp]={dx,0,0};
}
inline int randomlevel()
{
	int res=1;
	while (P*RAND_MAX>rand())
		res++;
	return res;
}
inline void view(int dx,int s)//加入值为 dx 的节点,深度为 s ;
{
	for (int i=1;i<=L;i++)
		skq[i]=0;
	int dw=1,ds=L;
	while (ds)
	{
		if (sk[dw].ne and sk[sk[dw].ne].x<dx)
			dw=sk[dw].ne;
		else
		{
			if (ds<=s)
				sk[++skp]={dx,sk[dw].ne,0},skq[s-ds+1]=dw,
				sk[dw].l+=sk[sk[dw].ne].l+1,sk[dw].ne=skp;
			dw++,ds--;
		}
	}
	
	sk[skq[s]].l=1,sk[skp].l=(sk[skp].ne)?1:0;
	for (int i=s;i>1;i--)//使用第 i 层的节点进行操作,维护第 i-1 层的边长 ;
	{
		if (sk[skp-s+i-1].ne)
			for (int j=skp-s+i;j!=sk[skp-s+i-1].ne+1;j=sk[j].ne)
				sk[skp-s+i-1].l+=sk[j].l;
		else
			break;
		sk[skq[i-1]].l-=sk[skp-s+i-1].l;
	}
}
inline void debug(int dx)//删除一个值为 dx 的节点 ; 
{
	int dw=1,ds=L;
	while (ds)
	{
		if (sk[dw].ne and sk[sk[dw].ne].x<dx)
			dw=sk[dw].ne;
		else
		{
			if (sk[sk[dw].ne].x==dx)
				sk[dw].l+=max(0,sk[sk[dw].ne].l-1),sk[dw].ne=sk[sk[dw].ne].ne;
			dw++,ds--;
		}
	}
}
inline int kth(int dx)//求第一个值为 dx 的节点排名 ;
{
	int dw=1,ds=L,res=0;
	while (ds)
	{
		if (sk[dw].ne and sk[sk[dw].ne].x<dx)
			res+=sk[dw].l,dw=sk[dw].ne;
		else
			dw++,ds--;
	}
	return res+1;
}
inline int defind(int k)//求第 k 小的节点值 ;
{
	int dw=1,ds=L;
	while (ds)
	{
		if (sk[dw].ne and sk[dw].l<=k)
			k-=sk[dw].l,dw=sk[dw].ne;
		else
			dw++,ds--;
	}
	return sk[dw-1].x;
}
inline int lower(int dx)//求值为 dx 的节点其前驱 ;
{
	int dw=1,ds=L;
	while (ds)
	{
		if (sk[dw].ne and sk[sk[dw].ne].x<dx)
			dw=sk[dw].ne;
		else
			dw++,ds--;
	}
	return sk[dw-1].x;
}
inline int upper(int dx)//求值为 dx 的节点其后继 ; 
{
	int dw=1,ds=L;
	while (ds)
	{
		if (sk[dw].ne and sk[sk[dw].ne].x<=dx)
			dw=sk[dw].ne;
		else
			dw++,ds--;
	}
	return sk[sk[dw-1].ne].x;
}
int main ()
{
//	freopen("skiplist.in","r",stdin);
//	freopen("skiplist.out","w",stdout);
	
	srand(time(0)),build(-INT_MAX);
	int op,x;
	read(n);
	
	while (n-->0)
	{
		read(op),read(x);
		switch (op)
		{
			case 1:
				view(x,randomlevel());
				break;
			
			case 2:
				debug(x);
				break;
			
			case 3:
				printf ("%d\n",kth(x));
				break;
			
			case 4:
				printf ("%d\n",defind(x));
				break;
			
			case 5:
				printf ("%d\n",lower(x));
				break;
			
			default:
				printf ("%d\n",upper(x));
		}
	}
	
	return 0;
}
/*
12
1 -2
1 2
1 3
1 0
1 2
1 1
5 1

2 0
5 1

2 2
4 4

6 1

0
-2
3
2
*/

2025/1/12 22:32
加载中...