Bzoj1056--Haoi2008排名系统

平衡树练习

还是很水的一道题(雾

反正字符串哈希一下会方便很多,其它都是常规操作也没什么好说的

平衡树写得挺繁杂的,以后可能去想想精简一点的版本,写是难写,但这种题一般写出来了就不会错(说完就PE了。。

代码:

#include<bits/stdc++.h>
#define MAXN 250005
#define MAXM 3005
#define INF 10000000000000LL
#define MOD 1000003
#define LL long long
using namespace std;

inline int Hash(char *s) {
    int ret=0;
    for(int i=strlen(s)-1;i>0;i--) ret=ret*27+s[i]-‘A‘+1,ret%=MOD;
    return ret;
}
struct elem{
    char s[15];int v;
};
vector<elem> table[MOD];
inline int _find(char *s) {
    int k=Hash(s);int lim=table[k].size(),ret=0;
    for(int i=0;i<lim;i++) {
        if(!strcmp(table[k][i].s+1,s+1)) ret=table[k][i].v;
    }
    return ret;
}

int n,bk[MAXN];
char s[15];

struct Node {
    int son[2],par,sz;LL v,r;
}x[MAXN];
struct Treap{
    int root,L,R,cnt;
    void init() {
        root=MAXN-2;L=0;R=1;cnt=0;
        x[root].v=INF;x[root].r=INF;
    }

    int pa,t;
    inline void rotate(int num,int p) {
        pa=x[num].par;t=x[num].sz;
        x[num].sz=x[pa].sz;x[pa].sz-=t-x[x[num].son[p]].sz;
        x[x[pa].par].son[x[x[pa].par].son[L]==pa?L:R]=num;x[num].par=x[pa].par;
        x[pa].son[p^1]=x[num].son[p];if(x[num].son[p]) x[x[num].son[p]].par=pa;
        x[pa].par=num;x[num].son[p]=pa;
    }

    void Del(int num) {
        while(x[num].son[R]|x[num].son[L])
            if(x[x[num].son[R]].r>x[x[num].son[L]].r) rotate(x[num].son[R],L);
            else rotate(x[num].son[L],R);
        int now=x[num].par;
        while(now) {x[now].sz--;now=x[now].par;}
        x[x[num].par].son[x[x[num].par].son[L]==num?L:R]=0;
    }
    void Insert(int num,int v) {
        int now=root,pre;
        x[num].sz=1;x[num].r=rand()%MOD;x[num].v=v;
        while(true) {
            pre=v>x[now].v?L:R;x[now].sz++;
            if(!x[now].son[pre]) {x[num].par=now;x[now].son[pre]=num;break;}
            now=x[now].son[pre];
        }
        while(x[num].r>x[x[num].par].r)
            rotate(num,x[x[num].par].son[L]==num?R:L);
    }
    void Updata(int num,int v,char *s) {
        if(!num) {
            int k=Hash(s);elem t;strcpy(t.s,s);t.v=++cnt;
            table[k].push_back(t),num=cnt;bk[cnt]=k;
        }
        Del(num);Insert(num,v);
    }

    bool Qurey_Treap(int v,int p) {
        if(x[root].sz<v) return 0;
        int now=x[root].son[R],lim;
        while(true) {
            if(x[x[now].son[L]].sz==v-1) break;
            if(x[x[now].son[L]].sz<v) v-=x[x[now].son[L]].sz+1,now=x[now].son[R];
            else now=x[now].son[L];
        }
        lim=table[bk[now]].size();
        for(int i=0;i<lim;i++) if(table[bk[now]][i].v==now) {
            if(p) printf(" %s",table[bk[now]][i].s+1);
            else printf("%s",table[bk[now]][i].s+1);
            return 1;
        }
    }
    inline void Qurey_P(int num) {
        int ret=x[x[num].son[L]].sz,now=num;
        while(now) {
            if(x[x[now].par].son[R]==now) ret+=x[x[x[now].par].son[L]].sz+1;
            now=x[now].par;
        }
        printf("%d\n",ret);
    }
    inline void Qurey_R(int k) {
        for(int i=0;i<10;i++) if(!Qurey_Treap(k+i,i)) break;printf("\n");
    }
};

int main() {
    srand(2333333);
    scanf("%d",&n);
    Treap p;p.init();
    LL a;
    for(int i=1;i<=n;i++) {
        scanf("%s",s);
        if(s[0]==‘+‘) {scanf("%lld",&a);p.Updata(_find(s),a,s);}
        if(s[0]==‘?‘) {
            if(s[1]>‘9‘) p.Qurey_P(_find(s));
            else {
                int len=strlen(s);a=0;
                for(int i=1;i<len;i++) a=a*10+s[i]-‘0‘;
                p.Qurey_R(a);
            }
        }
    }
    return 0;
}
时间: 2024-07-31 23:29:11

Bzoj1056--Haoi2008排名系统的相关文章

bzoj1056 [HAOI2008]排名系统【updating】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1056 [题解] 就是一棵splay..吧? 一种用map,一种用hash表 本地测hash表跑的飞快,甚至比网络上只跑1s的还快,还是T了...qwq 查不出啊(逃 先晾在这吧,坑再说 map版本: # include <map> # include <stdio.h> # include <string.h> # include <iostream>

【pb_ds】bzoj1056 [HAOI2008]排名系统/bzoj1862 [Zjoi2006]GameZ游戏排名系统

STL裸题,线下AC,bzoj无限RE ing…… 1 #include<cstdio> 2 #include<cctype> 3 #include<iostream> 4 #include<string> 5 #include<ext/pb_ds/assoc_container.hpp> 6 #include<ext/pb_ds/tree_policy.hpp> 7 using namespace std; 8 using name

数据结构(Splay平衡树):HAOI2008 排名系统

[HAOI2008] 排名系统 [题目描述] 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录. [输入] 第一行是一个整数n(10<=n<=250000)表示请求总数目.接下来n行,每行包含了一个请求.请求的具体格式如下: +Name Score 上传最新得分记录.Name表示玩家名字,由大写英文字母组成,不超

bzoj 1862/1056 [HAOI2008]排名系统

原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1862 很恶心的 一道题,我也不晓得自己是第几次写这题了%>_<%. 写了两种方法,平衡树+哈希和平衡树+map.哈希函数是抄别人的.比较了一下还是哈希快一些. 题意很简单,就不说了. 具体思路是,平衡树维护排名,map建立姓名和分数一一对应的关系. 求rank时题意默认是越先提交得分排名越靠前(相同得分的条件下). 具体如下: 平衡树+map 1 #include<algorit

P4291 [HAOI2008]排名系统

传送门 怎么主要写的都是平衡树,这种查询排名,查询第 $K$ 大的操作直接权值线段树就行了 把读入的数据离散化一波,然后开个 $map$ 维护每个人最后一次插入时在线段树上的位置,直接线段树维护就完事了 查询排名就询问大于它的节点数量,查询第 $K$ 大直接线段树上二分 就是数据格式比较恶心,细节有点多 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #inc

[haoi2008]排名系统

蛤省省选题. 一道彻头彻尾的码农题. 该题的主要知识点有:字符串hash,平衡树.(两颗平衡树?). 4T用splay怎么都调不过.可能是由于splay常数太大.(想写treap,但又实在不想写). 字符串hash不想写啊,用map水的话时限卡着. 这题就当我过了吧... 过不去的程序: #include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<

HNOI2008 and ZJOI2006 排名系统

1056: [HAOI2008]排名系统 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1311  Solved: 337[Submit][Status] Description 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录. Input 第一行是一个整数n(n

【HAOI2008】排名系统

[题目描述] 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录. [输入格式] 第一行是一个整数n(n>=10)表示请求总数目.接下来n行,每行包含了一个请求.请求的具体格式如下: +Name Score 上传最新得分记录.Name表示玩家名字,由大写英文字母组成,不超过10个字符.Score为最多8位的正整数.

BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 Splay

Splay的基本操作,比较繁琐..... 有个一坑点,sorce会超int 1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 913  Solved: 343 [Submit][Status][Discuss] Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家

BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]

1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1318  Solved: 498[Submit][Status][Discuss] Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家的名次相同时,先上传记录者优先.由于新游戏的火爆,网站服务器已经难堪重负.为此