求助替罪羊树(附赠数据)
查看原帖
求助替罪羊树(附赠数据)
109625
HKHbest楼主2021/2/23 16:33
#include<bits/stdc++.h>
using namespace std;
const int N=2000000;
int n,cnt=0,root,a[N],tot;
struct dian
{
	int ls,rs,siz,tsiz,number,val;
}d[N];
bool judge(int u)
{
	double pd=(double)max(d[d[u].ls].siz,d[d[u].rs].siz)/(double)d[u].siz; 
	if(pd<=0.25||pd>=0.75)
	{
		return true;
	}
	return false;
	// (a[k].wn&&(alpha*(double)a[k].size<(double)max(a[a[k].ls].size,a[a[k].rs].size)
	// ||(double)a[k].sh<alpha*(double)a[k].size));
}
void get(int u)
{
	if(d[u].ls)	get(d[u].ls);
	if(d[u].number)	a[++tot]=u;
	if(d[u].rs)	get(d[u].rs);
}
void update(int u)
{
	int ls=d[u].ls,rs=d[u].rs;
	d[u].tsiz=d[ls].tsiz+d[u].number+d[rs].tsiz;
	d[u].siz=d[ls].siz+1+d[rs].siz;
	return;
}
int rebuilt(int l,int r)
{
	if(l==r)
		return 0;
	int mid=(l+r)>>1;
	d[a[mid]].ls=rebuilt(l,mid);
	d[a[mid]].rs=rebuilt(mid+1,r);
	update(a[mid]);
	return a[mid];
}
void shutdown(int &u)
{
	get(u);
	u=rebuilt(1,tot+1);
	tot=0;
}
void insert(int &u,int v)
{
	if(u==0)
	{
		u=++cnt;
		d[u].val=v;
		d[u].siz=d[u].tsiz=d[u].number=1;
		if(!root)
			root=1;
		return;
	}
	else
	{
		if(v<d[u].val)
		{
			insert(d[u].ls,v);
		}
		else if(v>d[u].val)
		{
			insert(d[u].rs,v);
		}
		else
		{
			d[u].number++;
		}
		update(u);
		if(judge(u)==true)
			shutdown(u);
	}
}
void del(int &u,int v)
{
	d[u].tsiz--;
	if(v<d[u].val)
	{
		del(d[u].ls,v);
	}
	else if(v>d[u].val)
	{
		del(d[u].rs,v);
	}
	else
	{
		d[u].number--;
	}
	update(u);
	if(judge(u)==true)
		shutdown(u);
}
int rankup(int u,int v)
{
	if(u==0)	return 0;
	if(v<d[u].val)	return rankup(d[u].ls,v);
	else if(v>d[u].val)	return rankup(d[u].rs,v)+d[u].number+d[d[u].ls].tsiz;
	else if(v==d[u].val&&d[u].number)	return d[d[u].ls].tsiz+d[u].number;
	return 0;
}
int rankdown(int u,int v)
{
	if(u==0)	return 0;
	if(v<d[u].val)	return rankdown(d[u].ls,v);
	else if(v>d[u].val)	return rankdown(d[u].rs,v)+d[u].number+d[d[u].ls].tsiz;
	else if(v==d[u].val&&d[u].number)	return d[d[u].ls].tsiz;
	return 0;
}
/*
int rkup(int k,int x)
{
    if(!k) return 1;
    if(a[k].wn&&x==a[k].val) return 1+a[k].wn+a[a[k].ls].sh;
    else if(x<a[k].val) return rkup(a[k].ls,x);
    else return a[a[k].ls].sh+a[k].wn+rkup(a[k].rs,x); 
}

int rkdown(int k,int x)
{
    if(!k) return 0;
    if(a[k].wn&&a[k].val==x) return a[a[k].ls].sh;
    else if(x<a[k].val) return rkdown(a[k].ls,x);
    else return a[a[k].ls].sh+a[k].wn+rkdown(a[k].rs,x);    
}

*/
int rkis(int u,int k)
{
	if(d[u].ls==d[u].rs)
		return d[u].val;
	if(k<=d[d[u].ls].tsiz)	return rkis(d[u].ls,k);
	else if(k>d[d[u].ls].tsiz+d[u].number)	return rkis(d[u].rs,k-d[u].number-d[d[u].ls].tsiz);
	else return d[u].val;
}
int main()
{
//	freopen("out1.out","w",stdout);
//	freopen("in.in","r",stdin);
	freopen("P3369_6x.out","w",stdout);
	freopen("P3369_6x.in","r",stdin);
	
	scanf("%d",&n);
	for(int i=1,opt,x;i<=n;i++)
	{
		scanf("%d%d",&opt,&x);
		switch(opt)
		{
			case 1:
			{
				insert(root,x);
				break;
			}
			case 2:
			{
				del(root,x);
				break;
			}
			case 3:
			{
				printf("%d\n",rankdown(root,x)+1);
				break;
			}
			case 4:
			{
				printf("%d\n",rkis(root,x));
				break;
			}
			case 5:
			{
				printf("%d\n",rkis(root,rankdown(root,x)));
				break;
			}
			case 6:
			{
				printf("%d\n",rkis(root,rankup(root,x)+1));
				break;
			}
			default:
				break;
		}
	}
	return 0;
}

/*
插入 xx 数
删除 xx 数(若有多个相同的数,因只删除一个)
查询 xx 数的排名(排名定义为比当前数小的数的个数 +1+1 )
查询排名为 xx 的数
求 xx 的前驱(前驱定义为小于 xx,且最大的数)
求 xx 的后继(后继定义为大于 xx,且最小的数)
*/

数据生成

#include<bits/stdc++.h>
using namespace std;
int n,m,x,had[1000000],tot,y;
const int maxn=10000000;
bool checksame()
{
	if(tot<=1)
		return true;
	for(int i=1;i<tot;i++)
	{
		if(had[i]!=had[i+1])
		{
			y=i;
			return false;
		}
	}
	return true;
}
bool _checksame()
{
	if(tot<=1)
		return true;
	for(int i=tot;i>1;i--)
	{
		if(had[i]!=had[i-1])
		{
			y=i;
			return false;
		}
	}
	return true;
}
bool judge(int opt)
{
	switch(opt)
	{
		case 1:
			x=rand()%(maxn)+1;
			x*=rand()%2==0?1:(-1);
			had[++tot]=x;
			return true;
		case 2:
			if(tot==0) 			return false;
			x=rand()%tot+1;y=x;x=had[x];had[y]=0;
			for(int i=y;i<=tot;i++)
			{
				had[i]=had[i+1];
			}
			tot--;
			return true;
		case 3:
			if(tot==0) 			return false;
			x=had[rand()%tot+1];return true;
		case 4:
			if(tot==0)
				return false;
			x=rand()%tot+1;	
			return true;
		case 5:
			if(checksame())
				return false;
			x=had[rand()%(tot-y)+y+1];
			return true;
		case 6:
			if(_checksame())		
				return false;
			x=had[rand()%(tot-(tot-y+1))+1];
			return true;
		default:
			return false;
	}
}
int main()
{
	freopen("in.in","w",stdout);
	srand(time(0));
	n=100000;
	printf("%d\n",n);
	for(int i=1,opt;i<=n;i++)
	{
		do
		{
			opt=rand()%6+1;
		}
		while(judge(opt)==false);
		printf("%d %d\n",opt,x);
		sort(had+1,had+1+tot);
	}
	return 0;
}
2021/2/23 16:33
加载中...