蛋疼了几天总算过了
去年太傻逼调了好久的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;
}