Treap 36分,有WA、TLE,求调
查看原帖
Treap 36分,有WA、TLE,求调
817668
Hukaidi8566楼主2023/8/11 17:16

你好,我的代码 #3 WA、#4~10 TLE,我照着《信奥一本通(提高篇)》写的,不知道怎么修改。

#include<cstdio>
#include<cstdlib>
using namespace std;

#define lc(x) t[x].lc
#define rc(x) t[x].rc
#define v(x) t[x].key
#define p(x) t[x].pri
#define c(x) t[x].cnt
#define s(x) t[x].sze

const int nn=100001+1;
const int INF=0x3f3f3f3f;

struct node
{
	int lc,rc,key,pri,cnt,sze;
}t[nn];

int pool;
int rt;
int n;

inline void upt(const int&);

inline void Zig(int&);
inline void Zag(int&);

inline void Insert(int&,const int&);
inline void Delete(int&,const int&);

inline int QueryPre(const int&);
inline int QuerySuf(const int&);

inline int QueryKth(int);

inline int QueryRank(const int&);

inline int read();
inline void write(int);

int main()
{
	n=read();//scanf("%d",&n);
	//rt=1;        不能要!!! 
	for(int i=0;i<n;i++)
	{
		int x1,x2;
		//scanf("%d%d",&x1,&x2);
		x1=read();x2=read();
		if(x1==1) Insert(rt,x2);
		if(x1==2) Delete(rt,x2);
		if(x1==3) write(QueryRank(x2));//printf("%d\n",QueryRank(x2));
		if(x1==4) write(QueryKth(x2));//printf("%d\n",QueryKth(x2));
		if(x1==5) write(QueryPre(x2));//printf("%d\n",QueryPre(x2));
		if(x1==6) write(QuerySuf(x2));//printf("%d\n",QuerySuf(x2));
		if(x1>=3) putchar('\n');
	}
	return 0;
} 
inline void upt(const int &k)
{
	s(k)=s(lc(k))+s(rc(k))+c(k);
	return;
}
inline void Zig(int &k)
{
	int y=lc(k);
	lc(k)=rc(y);
	rc(y)=k;
	s(y)=s(k);
	upt(k);
	k=y;
}
inline void Zag(int &k)
{
	int y=rc(k);
	rc(k)=lc(y);
	lc(y)=k;
	s(y)=s(k);
	upt(k);
	k=y;
}
inline void Insert(int &k,const int &key)//插入 
{
	if(!k)
	{
		k=++pool;
		v(k)=key;
		p(k)=rand();
		c(k)=s(k)=1;
		lc(k)=rc(k)=0;
		return;
	}
	
	s(k)++;
	if(v(k)==key)
	{
		c(k)++;
	}
	else if(key<v(k))
	{
		Insert(lc(k),key);
		if(p(lc(k))<p(k)) Zig(k);
	}
	else
	{
		Insert(rc(k),key);
		if(p(rc(k))<p(k)) Zag(k);
	}
	return;
}
inline void Delete(int &k,const int &key)//删除 
{
	if(v(k)==key)
	{
		if(c(k)>1)
		{
			c(k)--;
			s(k)--;
		}
		else if(!lc(k)||!rc(k))
		{
			k=lc(k)+rc(k);
		}
		else if(p(lc(k))<p(rc(k)))
		{
			Zig(k);
			Delete(k,key);
		}
		return;
	}
	
	s(k)--;
	if(key<v(k))
	{
		Delete(lc(k),key);
	}
	else
	{
		Delete(rc(k),key);
	}
	return;
}
inline int QueryPre(const int &key)//前驱 
{
	int x=rt,res=-INF;
	while(x)
	{
		if(v(x)<=key)
		{
			res=v(x);
			x=rc(x);
		}
		else
		{
			x=lc(x);
		}
	}
	return res;
}
inline int QuerySuf(const int &key)//后继 
{
	int x=rt,res=INF;
	while(x)
	{
		if(v(x)>=key)
		{
			res=v(x);
			x=lc(x);
		}
		else
		{
			x=rc(x);
		}
	}
	return res;
}
inline int QueryKth(int k)//排名第 k
{
	int x=rt;
	while(x)
	{
		if(s(lc(x))<k&&s(lc(x))+c(x)>=k)
		{
			return v(x);
		}
		if(s(lc(x))>=k)
		{
			k=lc(x);
		}
		else
		{
			k-=s(lc(x))+c(x);
			x=rc(x);
		}
	}
	return 0;
}
inline int QueryRank(const int &key)//某个数的排名 
{
	int x=rt,res=0;
	while(x)
	{
		if(key==v(x))
		{
			return res+s(lc(x))+1;
		}
		if(key<v(x))
		{
			x=lc(x);
		}
		else
		{
			res+=s(lc(x))+c(x);
			x=rc(x);
		}
	}
	return res;
}
inline int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(!(ch>='0'&&ch<='9'||ch=='-')) ch=getchar();
	if(ch=='-') f=-1,ch=getchar();
	while(ch>='0'&&ch<='9')
	{
		x=x*10+(ch-'0');
		ch=getchar();
	}
	return x*f;
}
inline void write(int x)
{
	int sx[39],sy=1;
	if(x<0)
	{
		putchar('-');
		x=-x;
	}
	while(x)
	{
		sx[sy++]=x%10;
		x/=10;
	}
	for(int i=sy-1;i>=1;i--)
	{
		putchar(sx[i]+'0');
	}
	return;
}

后来我看到一组数据,也没有通过: 输入:

5
1 1
1 2
1 3
2 2
5 3

我的输出:

3

2023/8/11 17:16
加载中...