替罪羊树WA求助
查看原帖
替罪羊树WA求助
104963
Gary88楼主2020/12/30 17:47
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#define p 0.75
using namespace std;
int n,root,cnt,tot,ans;
queue<int>q;
struct node
{
	int ch[2],rch,tch,sz,w,tot,de,f;
}t[1000001];
struct pp
{
	int w,s;
}a[100001];
void divide(int x)
{
	if(!x)
	return;
	divide(t[x].ch[0]);
	if(!t[x].de)
	{
		a[++tot].w=t[x].w;
		a[tot].s=t[x].sz;	
	}
	divide(t[x].ch[1]);
	q.push(x);
	t[x].ch[0]=t[x].ch[1]=t[x].rch=t[x].tch=t[x].sz=t[x].w=t[x].tot=t[x].de=t[x].f=0;
}
int build(int l,int r,int fa)
{
	if(l>r)
	return 0;
	int mid=(l+r)>>1;
	int k=q.front();
	q.pop();
	t[k].w=a[mid].w;
	t[k].sz=a[mid].s;
	t[k].f=fa;
	t[k].ch[0]=build(l,mid-1,k);
	t[k].ch[1]=build(mid+1,r,k);
	t[k].rch=t[k].tch=1+t[t[k].ch[0]].tch+t[t[k].ch[1]].tch;
	t[k].tot=t[k].sz+t[t[k].ch[0]].tot+t[t[k].ch[1]].tot;
	return k;
}
bool need_rebuild(int x)
{
	return ((double(t[x].rch))/(double(t[x].tch))<p)||((double(t[t[x].ch[0]].tch))/(double(t[x].tch))>p)||((double(t[t[x].ch[1]].tch))/(double(t[x].tch))>p);
}
int find_rebuild(int x)
{
	if(t[x].f)
	{
		int k=find_rebuild(t[x].f);
		if(k)
		return k;
	}
	if(need_rebuild(x))
		return x;
	else
		return 0;
}
void update(int x,int y,int z,int k)
{
	if(!x)
	return;
	t[x].rch+=y;
	t[x].tch+=z;
	t[x].tot+=k;
	update(t[x].f,y,z,k);
}
int find(int rt,int x)
{
	int u=rt;
	while((t[u].ch[t[u].w<x])&&t[u].w!=x)
	{
		u=t[u].ch[t[u].w<x];
	}
	return u;
}
void insert(int &rt,int x)
{
	if(!rt)
	{
		int k=q.front();
		q.pop();
		rt=k;
		t[k].w=x;
		t[k].rch=t[k].tch=t[k].tot=t[k].sz=1;
		return;
	}
	int u=find(rt,x);
	if(t[u].w==x)
	{
		if(t[u].de)
		{
			t[u].de=0;
			t[u].sz=1;
			update(u,1,0,1);
		}
		else
		{
			t[u].sz++;
			update(u,0,0,1);
		}
	}
	else
	{
		int kk=q.front();
		q.pop();
		t[u].ch[t[u].w<x]=kk;
		t[kk].f=u;
		t[kk].sz=1;
		t[kk].w=x;
		update(kk,1,1,1);
		int k=find_rebuild(kk);
		if(k)
		{
			tot=0;
			int y=t[k].f,s=(t[y].ch[1]==k),g=t[k].tch;
			divide(k);
			int z=build(1,tot,y);
			if(y)
			t[y].ch[s]=z;
			else
			rt=z;
			update(y,0,t[z].tch-g,0);
		}
	}
}
void del(int &rt,int x)
{
	int u=find(rt,x);
	if(t[u].sz>1)
	{
		t[u].sz--;
		update(u,0,0,-1);
	}
	else
	{
		t[u].sz--;
		t[u].de=1;
		update(u,-1,0,-1);
		int k=find_rebuild(u);
//		printf("(%d)",k);
		if(k)
		{
			tot=0;
			int y=t[k].f,s=(t[y].ch[1]==k),g=t[k].tch;
			divide(k);
			int z=build(1,tot,y);
			if(y)
			t[y].ch[s]=z;
			else
			rt=z;
			update(y,0,t[z].tch-g,0);
		}
	}
}
int find1(int rt,int x)
{
	if(!rt)
	{
		return 1;
	}
	if(t[rt].w==x)
	{
		return t[t[rt].ch[0]].tot+1;
	}
	if(t[rt].w<x)
	{
		return t[rt].sz+t[t[rt].ch[0]].tot+find1(t[rt].ch[1],x);
	}
	else
	{
		return find1(t[rt].ch[0],x);
	}
}
int find2(int rt,int x)
{
	if(!rt)
	return 0;
	if(t[t[rt].ch[0]].tot>=x)
	{
		return find2(t[rt].ch[0],x);
	}
	else if(t[t[rt].ch[0]].tot+t[rt].sz<x)
	{
		return find2(t[rt].ch[1],x-t[t[rt].ch[0]].tot-t[rt].sz);
	}
	return t[rt].w;
}
void low(int rt,int x)
{
	if(!rt)
	return;
	if(t[rt].w<x)
	{
		if(!t[rt].de)
		ans=t[rt].w;
		low(t[rt].ch[1],x);
		return;
	}
	else
	{
		low(t[rt].ch[0],x);
		return;
	}
}
void high(int rt,int x)
{
	if(!rt)
	return;
	if(t[rt].w>x)
	{
		if(!t[rt].de)
		ans=t[rt].w;
		high(t[rt].ch[0],x);
		return;
	}
	else
	{
		high(t[rt].ch[1],x);
		return;
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=1000000;i++)
	q.push(i);
	while(n--)
	{
		int x,mode;
		scanf("%d%d",&mode,&x);
		switch(mode)
		{
			case 1:
				insert(root,x);
				break;
			case 2:
				del(root,x);
				break;
			case 3:
				printf("%d\n",find1(root,x));
				break;
			case 4:
				printf("%d\n",find2(root,x));
				break;
			case 5:
				low(root,x);
				printf("%d\n",ans);
				break;
			case 6:
				high(root,x);
				printf("%d\n",ans);
				break;
		}
//		tot=0;
//		divide(root);
//		for(int i=1;i<=tot;i++)
//		{
//			for(int j=1;j<=a[i].s;j++)
//			{
//				printf("%d ",a[i].w);
//			}
//		}
//		puts("");
	}
	return 0;
}
2020/12/30 17:47
加载中...