[HAOI2008]排名系统

蛋疼了几天总算过了

去年太傻逼调了好久的SBT都没过

flag:

1:再也不敢用模hash了

2:再也不敢鄙视STL了

flag完毕

题解:

平衡树裸题

下一步是文艺平衡树了233(又立flag...)

Code:

#include <cstdio>
#include <vector>
#include <cstring>
#include <map>
#include <string>
#define base 233
using namespace std;
map<unsigned int, unsigned int> M;
map<unsigned int, string> M2;
unsigned int hash(const string &s)
{
	unsigned int res(0);
	for (int i = 0;i < s.length(); ++i)
		res = res * base + s[i] - '0';
	return res;
}
struct Splay_Tree
{
	Splay_Tree *F, *Ls, *Rs;
	unsigned int Key;
	int Size, Num;
	vector<unsigned int> Person;
	inline void Clear()
	{
		F = Ls = Rs = NULL;
		Size = Num = Key = 0;
		Person.clear();
	}
	inline void Init(const unsigned int &x, const unsigned int &y)
	{
		Size = Num = 1;
		Key = x;
		Person.push_back(y);
	}
	inline void Update()
	{
		Size = Num;
		if (Ls)Size += Ls->Size;
		if (Rs)Size += Rs->Size;
	}
	inline void Zig()
	{
		Splay_Tree *p = Rs, *q = F;
		bool type;
		if (F->F)
			type = (F == F->F->Ls);
		Rs = F;
		F->Ls = p;
		F->Update();
		if (p)p->F = F;
		if (q)
		{
			F = q->F;
			q->F = this;
			if (!F)return;
			if (type)
				F->Ls = this;
			else
				F->Rs = this;
			F->Update();
		}
		Update();
		}
	inline void Zag()
	{
		Splay_Tree *p = Ls, *q = F;
		bool type;
		if (F->F)
			type = (F == F->F->Ls);
		Ls = F;
		F->Rs = p;
		F->Update();
		if (p)p->F = F;
		if (q)
		{
			F = q->F;
			q->F = this;
			if (!F)return;
			if (type)
				F->Ls = this;
			else
				F->Rs = this;
			F->Update();
		}
		Update();
	}
}*Root, T[290001], *res;
int tot(0), Q;
unsigned int num(0);
inline void Splay(Splay_Tree *s, Splay_Tree *t)
{
	if (!s)return;
	while(1)
	{
		if (s->F == t)
			break;
		if (s->F->F == t)
		{
			if (s->F->Ls == s)
				s->Zig();
			else
				s->Zag();
			break;
		}
		if (s->F->F->Ls == s->F)
		{
			if (s->F->Ls == s)
			{
				s->F->Zig();
				s->Zig();
			}
			else
			{
				s->Zag();
				s->Zig();
			}
		}
		else
		{
			if (s->F->Ls == s)
			{
				s->Zig();
				s->Zag();
			}
			else
			{
				s->F->Zag();
				s->Zag();
			}
		}
	}
	if (t == NULL)Root = s;
}
inline Splay_Tree *New()
{
	Splay_Tree *p = &T[tot++];
	p->Clear();
	return p;
}
inline void Insert(Splay_Tree *S, unsigned int x, unsigned int y)
{
	if (!Root)
	{
		Root = New();
		Root->Init(x, y);
		return;
	}
	else
	{
		Splay_Tree *p = S;
		while (1)
		{
			if (x == p->Key)
			{
				p->Num++;
				p->Size++;
				p->Person.push_back(y);
				Splay(p, Root->F);
				return;
			}
			if (x < p->Key)
			{
				if (p->Ls)
					p = p->Ls;
				else
				{
					p->Ls = New();
					p->Ls->Init(x, y);
					p->Ls->F = p;
					Splay(p->Ls, Root->F);
					return;
				}
			}
			else
			{
				if (p->Rs)
					p = p->Rs;
				else
				{
					p->Rs = New();
					p->Rs->Init(x, y);
					p->Rs->F = p;
					Splay(p->Rs, Root->F);
					return;
				}
			}
		}
	}
}
inline Splay_Tree *Maximum(Splay_Tree *s)
{
	if (!s)return NULL;
	return s->Rs ? Maximum(s->Rs) : s;
}
inline void Delete(Splay_Tree *s, unsigned int x, unsigned int y)
{
	if (!s)return;
	Splay_Tree *p = Root;
	while (p->Key != x)
	{
		if (p->Key > x)
			p = p->Ls;
		else
			p = p->Rs;
		if (!p)return;
	}
	if (p->Num == 1)
	{
		Splay(p, Root->F);
		Splay(Maximum(Root->Ls), Root);
		if (Root->Ls)
		{
			Root->Ls->Rs = Root->Rs;
			Root->Ls->F = NULL;
			if (Root->Rs)
				Root->Rs->F = Root->Ls;
			Root = Root->Ls;
		}
		else
		{
			if (Root->Rs)
			{
				Root->Rs->F = NULL;
				Root = Root->Rs;
			}
			else
				Root = NULL;
		}
	}
	else
	{
		for (int i = 0;i < p->Person.size(); ++i)
			if (p->Person[i] == y)
			{
				p->Person.erase(p->Person.begin()+i);
				break;
			}
		p->Num--;
		Splay(p, Root->F);
	}
}
inline Splay_Tree *Select(Splay_Tree *s, int x)
{
	if (!s)return 0;
	int now(0);
	if (s->Rs)
		now += s->Rs->Size;
	if (x >= now+1 && x <= now+s->Num)
	{
		Q = x-now-1;
		Splay(s, Root->F);
		return s;
	}
	if (x < now+1)
		return Select(s->Rs, x);
	else
		return Select(s->Ls, x-now-s->Num);
}
inline int rank(Splay_Tree *s, unsigned int x, unsigned int y)
{
	if (!s)return 0;
	int now(0);
	if (x == s->Key)
	{
		if (s->Rs)
			now += s->Rs->Size;
		for (int j = 0;j < s->Person.size(); ++j)
			if (s->Person[j] == y)
			{
				now += j+1;
				break;
			}
		Splay(s, Root->F);
		return now;
	}
	if (x < s->Key)
	{
		if (s->Rs)
			now += s->Rs->Size;
		now += s->Num;
		return now+rank(s->Ls, x, y);
	}
	else
		return rank(s->Rs, x, y);
}
unsigned int n, d, i, j, kk, now;
char c;
inline void read(unsigned int &x)
{
	for (c = getchar();c > '9' || c < '0';c = getchar());
	for (x = 0;c >= '0' && c <= '9';c = getchar())
		x = (x << 3) + (x << 1) + c - '0';
}
string S;
int main()
{
	scanf("%d", &n);
	getchar();
	while (n--)
	{
		c = getchar();
		d = 0;
		S.clear();
		switch (c) 
		{
			case ('+') :
			{
				for (c = getchar();c != ' ' && c != '\n';c = getchar())S += c;
				read(d);
				now = hash(S);
				if (M[now])
					Delete(Root, M[now], now);
				else
				{
					num++;
					M2[now] = S;
				}
				Insert(Root, d, now);
				M[now] = d;
				break;
			}
			case ('?') :
			{
				Q = 0;
				for (c = getchar();c != ' ' && c != '\n';c = getchar())S += c;
				if (S[0] >= '0' && S[0] <= '9')
				{
					for (i = 0;i < S.length(); ++i)d = (d << 3) + (d << 1) + S[i] - '0';
					for (i = d;i <= min(d+9, num);)
					{
						res = Select(Root, i);
						for (j = Q;j < res->Person.size(); ++j)
						{
							if (i > d)putchar(32);
							now = res->Person[j];
							for (kk = 0;kk < M2[now].length(); ++kk)
								putchar(M2[now][kk]);
							i++;
							if (i > min(d+9, num))
								break;
						}
					}
					puts("");
					break;
				}
				now = hash(S);
				printf("%d\n", rank(Root, M[now], now));
				break;
			}
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值