居然只是隔了就拿来当原题,这样真的好吗=。=
平衡树直接硬上,然后用哈希表存一下名字,其余的话就是裸操作了,要注意的是要加上一个时间标记,不然删的时候会炸。。
时间标记有几个地方忘记加上结果T了半天= =。
码了1个小时多,手酸了都= =4400B
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
using namespace std;
const int N=250001;
const int mo=985003;
struct treap
{
int v,s,l,r,time,rnd;
char ch[10];
};
int n,m,sz,root,tot,head[mo+1];
struct data1
{
int v,time,next;
char ch[10];
}hash[N];
treap t[N];
bool cmp(char a[],char b[])
{
for(int i=1;i<max(strlen(a),strlen(b));i++)
if (a[i]!=b[i])return 0;
return 1;
}
inline int Hash(char ch[])
{
int s=0;
for(int i=1;i<strlen(ch);i++)
{
s*=27;
s+=ch[i]-'A'+1;
s%=mo;
}
return s;
}
inline void rtl(int &x)
{
int y=t[x].r;
t[x].r=t[y].l;
t[y].l=x;
t[y].s=t[x].s;
t[x].s=t[t[x].l].s+t[t[x].r].s+1;
x=y;
}
inline void rtr(int &x)
{
int y=t[x].l;
t[x].l=t[y].r;
t[y].r=x;
t[y].s=t[x].s;
t[x].s=t[t[x].l].s+t[t[x].r].s+1;
x=y;
}
inline void del(int &k,int x,int time)
{
if (t[k].v==x)
{
if (t[k].time==time)
{
if (t[k].l*t[k].r==0)k=t[k].l+t[k].r;
else if (t[t[k].l].rnd<t[t[k].r].rnd){rtr(k),del(k,x,time);}
else {rtl(k),del(k,x,time);}
}
else if (time>t[k].time)
{
t[k].s--;
del(t[k].l,x,time);
}
else
{
t[k].s--;
del(t[k].r,x,time);
}
}
else if (x<t[k].v)
{
t[k].s--;
del(t[k].l,x,time);
}
else
{
t[k].s--;
del(t[k].r,x,time);
}
}
inline void ins(int &k,char ch[],int x,int time)
{
if (!k)
{
sz++;
k=sz;t[k].v=x;
t[k].s=1;
t[k].rnd=rand();
t[k].time=time;
memcpy(t[k].ch,ch,strlen(ch));
return;
}
t[k].s++;
if (x<=t[k].v)
{
ins(t[k].l,ch,x,time);
if (t[t[k].l].rnd<t[k].rnd)rtr(k);
}
else
{
ins(t[k].r,ch,x,time);
if (t[t[k].r].rnd<t[k].rnd)rtl(k);
}
}
inline void INS(char ch[],int x,int time)
{
int k=Hash(ch);
for(int i=head[k];i;i=hash[i].next)
{
if (cmp(hash[i].ch,ch))
{
del(root,hash[i].v,hash[i].time);
hash[i].time=time;
hash[i].v=x;
ins(root,ch,x,time);
return;
}
}
tot++;
hash[tot].time=time;
hash[tot].v=x;
memcpy(hash[tot].ch,ch,strlen(ch));
hash[tot].next=head[k];
head[k]=tot;
ins(root,ch,x,time);
}
inline int get(char ch[])
{
int k=Hash(ch);
for(int i=head[k];i;i=hash[i].next)
{
if (cmp(hash[i].ch,ch))return i;
}
}
inline int getrank(int k,int x,int time)
{
if (!k)return 0;
if (t[k].v==x)
{
if (t[k].time>time)return getrank(t[k].r,x,time);
else if (t[k].time<time)return 1+t[t[k].r].s+getrank(t[k].l,x,time);
else return t[t[k].r].s+1;
}
else if (t[k].v<x)return getrank(t[k].r,x,time);
else return 1+t[t[k].r].s+getrank(t[k].l,x,time);
}
inline void ask1(char ch[])
{
int t=get(ch);
printf("%d\n",getrank(root,hash[t].v,hash[t].time));
}
inline int index(int k,int x)
{
if (t[t[k].r].s+1==x)return k;
else if (x<=t[t[k].r].s)return index(t[k].r,x);
else return index(t[k].l,x-t[t[k].r].s-1);
}
inline void ask2(char ch[])
{
int s=0;
for(int i=1;i<strlen(ch);i++){s*=10;s+=ch[i]-'0';}
for(int i=s;i<=tot&&i<=s+9;i++)
{
printf("%s",t[index(root,i)].ch+1);
if (i<tot&&i<s+9)printf(" ");
}
printf("\n");
}
int main()
{
scanf("%d",&n);
char ch[11];
int x;
for(int i=1;i<=n;i++)
{
scanf("%s",ch);
if (ch[0]=='+')
{
scanf("%d",&x);
INS(ch,x,i);
}
else if (ch[1]<='Z'&&ch[1]>='A')ask1(ch);
else ask2(ch);
}
return 0;
}

本文介绍了一个结合平衡树和哈希表的数据结构实现案例。通过使用C++编程语言,详细展示了如何处理数据的插入、删除及查询操作,并特别强调了时间标记的重要性。

被折叠的 条评论
为什么被折叠?



