题目大意:维护动态修改,查询排名,查询排名从l开始后10人的姓名
题解:hash一下直接上平衡树
按照分数降序,第二关键字为时间升序排序,这个处理一下就可以了……
输出区间的操作理论上应该把区间提取出来然后中序遍历输出,但是我懒得写了……
然后我因为hash挂了调了2h……改成双模终于过了……
我的收获:数据结构劲啊
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <map>
using namespace std;
#define ll long long
#define pii pair<ll,ll>
const ll N=550005;
ll n,cnt,TOTP;
char opt[15];
map<pii,ll> vis;
pii gethash()
{
ll seed=0;pii has;
for(ll i=1;opt[i];i++) seed=seed*277+opt[i]-'A'+1,seed%=987654323;
has.first=seed;
for(ll i=1;opt[i];i++) seed=seed*2333+opt[i],seed%=666666431;
has.second=seed;
return has;
}
struct fhqtreap{
ll root;
ll c[N][2],rk[N],size[N];
ll k[N];
char name[N][13];
ll new_node(ll v)
{
size[++cnt]=1;
k[cnt]=v;
rk[cnt]=rand();
memcpy(name[cnt],opt,strlen(opt));
return cnt;
}
void update(ll x){size[x]=size[c[x][0]]+size[c[x][1]]+1;}
ll merge(ll x,ll y)
{
if(!x||!y) return x+y;
if(rk[x]<rk[y])
{
c[x][1]=merge(c[x][1],y);
update(x);
return x;
}
else
{
c[y][0]=merge(x,c[y][0]);
update(y);
return y;
}
}
void split(ll now,ll w,ll &x,ll &y)
{
if(!now) x=y=0;
else
{
if(k[now]<=w)
x=now,split(c[now][1],w,c[now][1],y);
else
y=now,split(c[now][0],w,x,c[now][0]);
update(now);
}
}
void del(pii am)
{
ll x,y,z;
split(root,vis[am],x,z);
split(x,vis[am]-1,x,y);
y=merge(c[y][0],c[y][1]);
root=merge(merge(x,y),z);
}
void ins(pii am,ll v)
{
if(vis[am]) del(am),TOTP--;
vis[am]=v,TOTP++;
ll x,y;
split(root,v,x,y);
root=merge(merge(x,new_node(v)),y);
}
ll getrank(pii am)
{
ll x,y;
split(root,vis[am]-1,x,y);
printf("%d\n",size[x]+1);
root=merge(x,y);
}
ll kth(ll now,ll w)
{
while(1)
{
if(w<=size[c[now][0]]) now=c[now][0];
else if(w==size[c[now][0]]+1) return now;
else w-=size[c[now][0]]+1,now=c[now][1];
}
}
void ask(ll l,ll r)
{
for(ll i=l;i<=r;i++){
ll out=kth(root,i),len=strlen(name[out]);
for(ll j=1;j<len;j++) putchar(name[out][j]);
if(i<r) putchar(' ');
}
putchar('\n');
}
}T;
void init()
{
scanf("%d",&n);
ll vakl;
for(ll i=1;i<=n;i++){
scanf("%s",opt);
if(opt[0]=='+'){
scanf("%lld",&vakl);
T.ins(gethash(),-vakl*300000+i);
}
else if(opt[0]=='?'&&opt[1]>='A'&&opt[1]<='Z'){
T.getrank(gethash());
}
else{
ll str=0,len=strlen(opt);
for(ll j=1;j<len;j++) str=str*10+opt[j]-'0';
T.ask(str,min(str+9,TOTP));
}
}
}
int main()
{
init();
return 0;
}