学 OI wiki 的替罪羊树,第 11 个点 WA 了,求助
查看原帖
学 OI wiki 的替罪羊树,第 11 个点 WA 了,求助
98618
Provicy楼主2020/4/26 20:05

RT

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#define ri register
#define inf 0x7fffffff
#define E (1)
#define mk make_pair
//#define int long long
using namespace std; const int N=200010; const double alpha=0.75;
inline int read()
{
	int s=0, w=1; ri char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-') w=-1; ch=getchar(); }
	while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+(ch^48), ch=getchar(); return s*w;
}
void print(int x) {if(x<0) x=-x, putchar('-'); if(x>9) print(x/10); putchar(x%10+'0'); }
int n,ch[N][2],w[N],root,cnt,wn[N],size[N],sized[N],fg[N];
#define mid (l+r>>1)
inline void Calc(int x)
{
	size[x]=size[ch[x][0]]+size[ch[x][1]]+wn[x];
	sized[x]=sized[ch[x][0]]+sized[ch[x][1]]+wn[x];
}
inline bool Cancg(int x) { return wn[x]&&(alpha*size[x]<=(double)max(size[ch[x][0]],size[ch[x][1]]) || (double)sized[x]<=alpha*size[x]); }
inline void qzbl(int x,int& tot)
{
	if(!x) return;
	qzbl(ch[x][0],tot);
	if(wn[x]) fg[tot++]=x;
	qzbl(ch[x][1],tot);
}
int ReBuild(int l,int r)
{
	if(l>=r) return 0;
	ch[fg[mid]][0]=ReBuild(l,mid);
	ch[fg[mid]][1]=ReBuild(mid+1,r);
	Calc(fg[mid]); return fg[mid];
}
void ReX(int& x)
{
	int tot=0;
	qzbl(x,tot);
	x=ReBuild(0,tot);
}
void Insert(int& x,int p)
{
	if(!x)
	{
		x=++cnt; if(!root) root=1;
		w[x]=p, ch[x][0]=ch[x][1]=0, size[x]=sized[x]=wn[x]=1;
	}
	else
	{
		if(w[x]==p) wn[x]++;
		else if(w[x]<p) Insert(ch[x][1],p);
		else Insert(ch[x][0],p);
		Calc(x); if(Cancg(x)) ReX(x);
	}
}
void Delete(int& x,int p)
{
	if(!x) return;
	sized[x]--;
	if(w[x]==p)
	{
		if(wn[x]) wn[x]--;
	}
	else
	{
		if(w[x]<p) Delete(ch[x][1],p);
		else Delete(ch[x][0],p);
		Calc(x);
	}
	if(Cancg(x)) ReX(x);
}
int Uprbd(int x,int p)
{
	if(!x) return 1;
	if(wn[x]&&w[x]==p) return sized[ch[x][0]]+wn[x]+1;
	if(w[x]>p) return Uprbd(ch[x][0],p);
	return sized[ch[x][0]]+wn[x]+Uprbd(ch[x][1],p);
}
int Lurbd(int x,int p)
{
	if(!x) return 0;
	if(wn[x]&&w[x]==p) return sized[ch[x][0]];
	if(w[x]<p) return sized[ch[x][0]]+Lurbd(ch[x][1],p)+wn[x];
	return Lurbd(ch[x][0],p);
}
int FindX(int x,int p)
{
	if(!x) return 0;
	if(sized[ch[x][0]]<p&&p<=sized[ch[x][0]]+wn[x]) return w[x];
	if(sized[ch[x][0]]+wn[x]<p) return FindX(ch[x][1],p-sized[ch[x][0]]-wn[x]);
	return FindX(ch[x][0],p);
}
inline int GetPre(int x,int p) { return FindX(x,Lurbd(x,p)); }
inline int GetNxt(int x,int p) { return FindX(x,Uprbd(x,p)); }
signed main()
{
	n=read();
	for(ri int i=1;i<=n;i++)
	{
		int opt=read(), x=read();
		if(opt==1) Insert(root,x);
		if(opt==2) Delete(root,x);
		if(opt==3) printf("%lld\n",Lurbd(root,x)+1);
		if(opt==4) printf("%lld\n",FindX(root,x));
		if(opt==5) printf("%lld\n",GetPre(root,x));
		if(opt==6) printf("%lld\n",GetNxt(root,x));
	}
	return 0;
}
2020/4/26 20:05
加载中...