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>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e5 + 10;
const int mod = 1e9+7;

struct pa {
    int v; ull h;
    pa() {}
    pa(int v, ull h) : v(v), h(h) {}
    friend bool operator == (pa a, pa b) {
        return a.v == b.v && a.h == b.h;
    }
};

int total, ind = 0, tid = 0;
map<ull, int> mp, tim;

char fys[M][12];

struct Splay {
    int ch[M][2], sz[M], fa[M], tm[M], siz, rt;
    pa val[M];
    int re[M], rn;

    inline void set() {
        siz = rn = 0;
    }

    inline int newnode() {
        int x = rn ? re[rn--] : (++siz);
        fa[x] = ch[x][0] = ch[x][1] = 0, sz[x] = 1; tm[x] = 0;
        return x;
    }

    inline void up(int x) {
        if(!x) return ;
        sz[x] = 1 + sz[ch[x][0]] + sz[ch[x][1]];
    }

    inline void rotate(int x, int &rt) {
        int y = fa[x], z = fa[y], ls = ch[y][1] == x, rs = ls^1;
        if(y == rt) rt = x;
        else ch[z][ch[z][1] == y] = x;
        fa[ch[x][rs]] = y, fa[y] = x, fa[x] = z;
        ch[y][ls] = ch[x][rs]; ch[x][rs] = y;
        up(y), up(x);
    }

    inline void splay(int x, int &rt) {
        while(x != rt) {
            int y = fa[x], z = fa[y];
            if(y != rt) {
                if((ch[z][0] == y)^(ch[y][0] == x)) rotate(x, rt);
                else rotate(y, rt);
            }
            rotate(x, rt);
        }
    }

    inline bool cmp(pa t, pa p) {
        return t.v > p.v;
    }

    inline void ins(pa t, int tt) {
        int x = rt, y, te;
        while(1) {
            te = cmp(t, val[x]);
            y = ch[x][te];
            if(!y) {
                y = newnode();
                val[y] = t; tm[y] = tt;
                fa[y] = x; ch[x][te] = y;
                break;
            }
            x = y;
        }
        splay(x, rt);
    }

    inline int find(int x, int rk) {
        if(sz[ch[x][0]] + 1 == rk) return x;
        if(sz[ch[x][0]] + 1 < rk) return find(ch[x][1], rk - sz[ch[x][0]] - 1);
        else return find(ch[x][0], rk);
    }

    inline int find(int x, pa t, int tt) {
        if(t.v == val[x].v && tt == tm[x]) return x;
        if(t.v < val[x].v || (t.v == val[x].v && tt > tm[x])) return findrk(ch[x][0], t, tt);
        else return findrk(ch[x][1], t, tt);
    }

    inline int gmax(int x) {
        while(ch[x][1]) x = ch[x][1];
        return x;
    }

    inline int gmin(int x) {
        while(ch[x][0]) x = ch[x][0];
        return x;
    }

    inline void del(pa t) {
        int x = find(rt, t, tim[t.h]);
        splay(x, rt);
        int pre = gmax(ch[x][0]), nxt = gmin(ch[x][1]);
        splay(pre, rt); splay(nxt, ch[pre][1]);
        ch[nxt][0] = 0, fa[x] = 0; ch[x][0] = ch[x][1] = 0; tm[x] = 0;
        re[++rn] = x;                 // reuse
    }

    inline void INS(pa t, int tt) {
        if(mp.count(t.h)) {
            int tv = mp[t.h];
            del(pa(tv, t.h));
        } else ++total;
        ins(t, tt); mp[t.h] = t.v;
    }

    inline int findrk(int x, pa t, int tt) {
        if(t.v == val[x].v && tt == tm[x]) return sz[ch[x][0]] + 1;
        if(t.v < val[x].v || (t.v == val[x].v && tt > tm[x])) return findrk(ch[x][0], t, tt);
        else return sz[ch[x][0]] + 1 + findrk(ch[x][1], t, tt);
    }

    inline int RANK(ull h) {
        pa t = pa(mp[h], h); int tt = tim[h];
        int ret = findrk(rt, t, tt);
        return total - ret;
    }

    bool fir;
    inline void prt(int x) {
        if(!x) return;
        prt(ch[x][1]);
        if(fir) fir = 0;
        else printf(" ");
//        cout << val[x].h << endl;
        printf("%s", fys[tm[x]]);
        prt(ch[x][0]);
    }

    inline int PRT(int rk) {
        int ed = total - rk;
        rk = total - rk - min(10, total - 1 - rk) + 1;// cout << "rk = " << rk << endl;
//        debug(rt);
        int x = find(rt, rk - 1), y = find(rt, ed + 1);// cout << x << ‘ ‘ << y << endl;
        splay(x, rt); splay(y, ch[x][1]);
        fir = 1; prt(ch[y][0]); puts("");
    }

    inline void debug(int x) {
        if(!x) return ;
        debug(ch[x][0]);
        cout << "x = " << x << ", fa = " << fa[x] << ", ls = " << ch[x][0] << ", rs = " << ch[x][1] << ", val = {" << val[x].v << ", " << val[x].h << "}, sz = " << sz[x] << ", tm = " << tm[x] << endl;
        debug(ch[x][1]);
    }

}T;

char str[23];
ull bin[23];

inline ull ghash(char *t) {
    ull ret = 0;
    for (int i=0; t[i]; ++i)
        ret = ret + (t[i] - ‘A‘) * bin[i];
    return ret;
}

inline int toint(char *t) {
    int ret = 0;
    for (int i=0; t[i]; ++i)
        ret = ret * 10 + t[i] - ‘0‘;
    return ret;
}

int main() {
    bin[0] = 1;
    for (int i=1; i<=20; ++i) bin[i] = bin[i-1] * 20000713;
    int Q, v; cin >> Q;
    T.set(); total = 2;
    // insert v
    T.siz = 2; T.rt = 1;
    T.ch[1][0] = T.ch[2][1] = T.ch[2][0] = 0; T.fa[1] = 0;
    T.val[1] = pa(-2147483648, 233), T.val[2] = pa(2147483647, 233);
    T.ch[1][1] = 2; T.fa[2] = 1; T.sz[1] = 2, T.sz[2] = 1;
    while(Q--) {
//        T.debug(T.rt);
        scanf("%s", &str);
        if(str[0] == ‘+‘) {
            scanf("%d", &v);
            ull ha = ghash(str+1);
            if(!tim.count(ha)) {
                tim[ha] = ++tid;
                for (int i=1; str[i]; ++i)
                    fys[tid][i-1] = str[i];
            }
            T.INS(pa(v, ha), tim[ha]);
        } else {
            if(isdigit(str[1])) T.PRT(toint(str+1));
            else printf("%d\n", T.RANK(ghash(str+1)));
        }
    }
    return 0;
}
/*
20
+ADAM 1000000
+BOB 1000000
+TOM 2000000
+CATHY 10000000
?TOM
?1
+DAM 100000
+BOB 1200000
+ADAM 900000
+FRANK 12340000
+LEO 9000000
+KAINE 9000000
+GRACE 8000000
+WALT 9000000
+SANDY 8000000
+MICK 9000000
+JACK 7320000
?2
?5
?KAINE
*/

hash表版本:

# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 2.5e5 + 10, N = 2.5e5 + 10;
const int mod = 985003;

struct pa {
    int v, h;
    pa() {}
    pa(int v, int h) : v(v), h(h) {}
    friend bool operator == (pa a, pa b) {
        return a.v == b.v && a.h == b.h;
    }
};

int total, tid = 0;

char str[23];

int head[mod + 5], nxt[N], to[N], w[N], tot = 0;
char tch[N][12];
inline void add(int u, int v, int tw, char *str) {
    ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
    for (int i=0; str[i]; ++i) tch[tot][i] = str[i];
    w[tot] = tw;
}

struct Splay {
    int ch[M][2], sz[M], fa[M], tm[M], siz, rt;
    pa val[M];
    int re[M], rn;

    inline void set() {
        siz = rn = 0;
    }

    inline int newnode() {
        int x = rn ? re[rn--] : (++siz);
        fa[x] = ch[x][0] = ch[x][1] = 0, sz[x] = 1; tm[x] = 0;
        return x;
    }

    inline void up(int x) {
        if(!x) return ;
        sz[x] = 1 + sz[ch[x][0]] + sz[ch[x][1]];
    }

    inline void rotate(int x, int &rt) {
        int y = fa[x], z = fa[y], ls = ch[y][1] == x, rs = ls^1;
        if(y == rt) rt = x;
        else ch[z][ch[z][1] == y] = x;
        fa[ch[x][rs]] = y, fa[y] = x, fa[x] = z;
        ch[y][ls] = ch[x][rs]; ch[x][rs] = y;
        up(y), up(x);
    }

    inline void splay(int x, int &rt) {
        while(x != rt) {
            int y = fa[x], z = fa[y];
            if(y != rt) {
                if((ch[z][0] == y)^(ch[y][0] == x)) rotate(x, rt);
                else rotate(y, rt);
            }
            rotate(x, rt);
        }
    }

    inline bool cmp(pa t, pa p) {
        return t.v > p.v;
    }

    inline void ins(pa t, int tt) {
        int x = rt, y, te;
        while(1) {
            te = cmp(t, val[x]);
            y = ch[x][te];
            if(!y) {
                y = newnode();
                val[y] = t; tm[y] = tt;
                fa[y] = x; ch[x][te] = y;
                break;
            }
            x = y;
        }
        splay(x, rt);
    }

    inline int find(int x, int rk) {
        if(sz[ch[x][0]] + 1 == rk) return x;
        if(sz[ch[x][0]] + 1 < rk) return find(ch[x][1], rk - sz[ch[x][0]] - 1);
        else return find(ch[x][0], rk);
    }

    inline int find(int x, pa t, int tt) {
        if(t.v == val[x].v && tt == tm[x]) return x;
        if(t.v < val[x].v || (t.v == val[x].v && tt > tm[x])) return findrk(ch[x][0], t, tt);
        else return findrk(ch[x][1], t, tt);
    }

    inline int gmax(int x) {
        while(ch[x][1]) x = ch[x][1];
        return x;
    }

    inline int gmin(int x) {
        while(ch[x][0]) x = ch[x][0];
        return x;
    }

    inline void del(pa t, int tim) {
        int x = find(rt, t, tim);
        splay(x, rt);
        int pre = gmax(ch[x][0]), nxt = gmin(ch[x][1]);
        splay(pre, rt); splay(nxt, ch[pre][1]);
        ch[nxt][0] = 0, fa[x] = 0; ch[x][0] = ch[x][1] = 0; tm[x] = 0;
        re[++rn] = x;                 // reuse
    }

    inline void INS(pa t) {
        int tim = -1, tv;
        for (int i=head[t.h]; i; i=nxt[i])
            if(strcmp(tch[i], str+1) == 0) {
                tim = to[i]; tv = w[i];
                break;
            }
        if(tim != -1) del(pa(tv, t.h), tim);
        else {
            ++total; ++tid; tim = tid;
            add(t.h, tid, t.v, str+1);
        }
        ins(t, tim);
    }

    inline int findrk(int x, pa t, int tt) {
        if(t.v == val[x].v && tt == tm[x]) return sz[ch[x][0]] + 1;
        if(t.v < val[x].v || (t.v == val[x].v && tt > tm[x])) return findrk(ch[x][0], t, tt);
        else return sz[ch[x][0]] + 1 + findrk(ch[x][1], t, tt);
    }

    inline int RANK(int h) {
        int tt, tv;
        for (int i=head[h]; i; i=nxt[i])
            if(strcmp(tch[i], str+1) == 0) {
                tt = to[i]; tv = w[i];
                break;
            }
        pa t = pa(tv, h);
        int ret = findrk(rt, t, tt);
        return total - ret;
    }

    bool fir;
    inline void prt(int x) {
        if(!x) return;
        prt(ch[x][1]);
        if(fir) fir = 0;
        else printf(" ");
//        cout << val[x].h << endl;
        for (int i=head[val[x].h]; i; i=nxt[i])
            if(to[i] == tm[x]) { printf("%s", tch[tm[x]]); break; }
        prt(ch[x][0]);
    }

    inline int PRT(int rk) {
        int ed = total - rk;
        rk = total - rk - min(10, total - 1 - rk) + 1;// cout << "rk = " << rk << endl;
//        debug(rt);
        int x = find(rt, rk - 1), y = find(rt, ed + 1);// cout << x << ‘ ‘ << y << endl;
        splay(x, rt); splay(y, ch[x][1]);
        fir = 1; prt(ch[y][0]); puts("");
    }

    inline void debug(int x) {
        if(!x) return ;
        debug(ch[x][0]);
        cout << "x = " << x << ", fa = " << fa[x] << ", ls = " << ch[x][0] << ", rs = " << ch[x][1] << ", val = {" << val[x].v << ", " << val[x].h << "}, sz = " << sz[x] << ", tm = " << tm[x] << endl;
        debug(ch[x][1]);
    }

}T;

inline int ghash(char *t) {
    int ret = 0;
    for (int i=0; t[i]; ++i)
        ret = 1ll * ret * 20000713 % mod + t[i] - ‘A‘;
    return ret % mod;
}

inline int toint(char *t) {
    int ret = 0;
    for (int i=0; t[i]; ++i)
        ret = ret * 10 + t[i] - ‘0‘;
    return ret;
}

int main() {
    int Q, v; cin >> Q;
    T.set(); total = 2;
    // insert v
    T.siz = 2; T.rt = 1;
    T.ch[1][0] = T.ch[2][1] = T.ch[2][0] = 0; T.fa[1] = 0;
    T.val[1] = pa(-2147483648, 233), T.val[2] = pa(2147483647, 233);
    T.ch[1][1] = 2; T.fa[2] = 1; T.sz[1] = 2, T.sz[2] = 1;
    while(Q--) {
//        T.debug(T.rt);
        scanf("%s", &str);
        if(str[0] == ‘+‘) {
            scanf("%d", &v);
            T.INS(pa(v, ghash(str+1)));
        } else {
            if(isdigit(str[1])) T.PRT(toint(str+1));
            else printf("%d\n", T.RANK(ghash(str+1)));
        }
    }
    return 0;
}
/*
20
+ADAM 1000000
+BOB 1000000
+TOM 2000000
+CATHY 10000000
?TOM
?1
+DAM 100000
+BOB 1200000
+ADAM 900000
+FRANK 12340000
+LEO 9000000
+KAINE 9000000
+GRACE 8000000
+WALT 9000000
+SANDY 8000000
+MICK 9000000
+JACK 7320000
?2
?5
?KAINE
*/

时间: 2024-11-06 19:36:21

bzoj1056 [HAOI2008]排名系统【updating】的相关文章

【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为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家的名次相同时,先上传记录者优先.由于新游戏的火爆,网站服务器已经难堪重负.为此