【求助】平衡树板子题中的玄学事故
查看原帖
【求助】平衡树板子题中的玄学事故
190485
CH_mengxiang楼主2022/8/26 13:36

insert里的一堆cout<<k;是调试用的。 实测样例第一个插入中tr[k].r=0;执行完后k出事了(1变成0了),除了第一行输出了个0以外其他都对了。有人帮一下吗

#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
struct node
{
	int l,r,n,c,p,s;
}tr[100001];
int root=1,tot=0;
inline void zig(int &k)
{
	int y=tr[k].l;
	tr[k].l=tr[y].r;
	tr[y].r=k;
	tr[y].s=tr[k].s;
	tr[k].s=tr[tr[k].l].s+tr[tr[k].r].s+tr[k].c;
	k=y;
}
inline void zag(int &k)
{
	int y=tr[k].r;
	tr[k].r=tr[y].l;
	tr[y].l=k;
	tr[y].s=tr[k].s;
	tr[k].s=tr[tr[k].l].s+tr[tr[k].r].s+tr[k].c;
	k=y;
}
void insert(int &k,int val)
{
	if (!k)
	{
						cout<<k;
		k=++tot;		cout<<k;
		tr[k].n=val;	cout<<k;
		tr[k].p=rand();	cout<<k;
		tr[k].c=1;		cout<<k;
		tr[k].s=1;		cout<<k;
		tr[k].l=0;		cout<<k;
		tr[k].r=0;		cout<<k<<endl;
		return;
	}
	else tr[k].s++;
	if (tr[k].n==val) tr[k].c++;
	else if (tr[k].n>val)
	{
		insert(tr[k].l,val);
		if (tr[k].p>tr[tr[k].l].p) zig(k);
	}
	else
	{
		insert(tr[k].r,val);
		if (tr[k].p>tr[tr[k].r].p) zag(k);
	}
}
void del(int &k,int val)
{
	if (tr[k].n==val)
	{
		if (tr[k].c>1) tr[k].c--,tr[k].s--;
		else if (!tr[k].l||!tr[k].r) k=tr[k].l+tr[k].r;
		else if (tr[tr[k].l].p<tr[tr[k].r].p)
		{
			zig(k);del(k,val);
		}
		else
		{
			zag(k);del(k,val);
		}
	}
	else
	{
		tr[k].s--;
		if (tr[k].n>val) del(tr[k].l,val);
		else del(tr[k].r,val);
	}
}
inline int pred(int k)
{
	int ans=-1e9,x=root;
	while (x)
	{
		if (tr[x].n<=k) ans=tr[x].n,x=tr[x].r;
		else x=tr[x].l;
	}
	return ans;
}
inline int succ(int k)
{
	int ans=1e9,x=root;
	while (x)
	{
		if (tr[x].n>=k) ans=tr[x].n,x=tr[x].l;
		else x=tr[x].r;
	}
	return ans;
}
inline int Rank(int val)
{
	int ans=0,x=root;
	while (x)
	{
		if (val==tr[x].n) return ans+tr[tr[x].l].s+1;
		if (val>tr[x].n) x=tr[x].r,ans+=tr[tr[x].l].s+tr[x].c;
		else x=tr[x].l;
	}
	return ans;
}
inline int kth(int k)
{
	int x=root;
	while (x)
	{
		if (tr[tr[x].l].s<k&&tr[tr[x].l].s+tr[x].c>=k) return tr[x].n;
		if (tr[tr[x].l].s>=k) x=tr[x].l;
		else k-=tr[tr[x].l].s+tr[x].c,x=tr[x].r;
	}
	return 0;
}
inline int Min(int x,int y)
{
	return x<y?x:y;
}
int main()
{
	int n,x,y;
	scanf("%d",&n);
	while (n--)
	{
		scanf("%d%d",&x,&y);
		switch(x)
		{
			case 1:insert(root,y);break;
			case 2:del(root,y);break;
			case 3:printf("%d\n",Rank(y));break;
			case 4:printf("%d\n",kth(y));break;
			case 5:printf("%d\n",pred(y));break;
			case 6:printf("%d\n",succ(y));break;
		}
	}
	return 0;
}

2022/8/26 13:36
加载中...