Wikioi 1985 GameZ游戏排名系统

来源:互联网 发布:php将数组转化成json 编辑:程序博客网 时间:2024/06/05 02:59

题目链接:http://wikioi.com/problem/1985/

解题代码(Trie):

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <ctype.h>#include <iostream>using namespace std;const int maxn = 250005;typedef struct node {int sub;struct node* next[26];}node, *leaf;// Trieleaf root = NULL;// Listint len = 1, score[maxn], seq[maxn];char name[maxn][12];// Size Balenced Treeint T = 0, LEN = 1;int s[maxn], l[maxn], r[maxn], p[maxn]; // subinline leaf getNode() {int i;leaf p = (leaf)malloc(sizeof(node));p->sub = 0;for (i = 0; i < 26; i++)p->next[i] = NULL;return p;}inline void l_rt(int& t) {int k = r[t];r[t] = l[k];l[k] = t;s[k] = s[t];s[t] = s[l[t]] + s[r[t]] + 1;t = k;}inline void r_rt(int& t) {int k = l[t];l[t] = r[k];r[k] = t;s[k] = s[t];s[t] = s[l[t]] + s[r[t]] + 1;t = k;}void Maintain(int& t, int flag) {if (flag == 0) {if (s[l[l[t]]] > s[r[t]])r_rt(t);else if (s[r[l[t]]] > s[r[t]])l_rt(l[t]), r_rt(t);elsereturn;} else {if (s[r[r[t]]] > s[l[t]])l_rt(t);else if (s[l[r[t]]] > s[l[t]])r_rt(r[t]), l_rt(t);elsereturn;}Maintain(l[t], 0);Maintain(r[t], 1);Maintain(t, 0);Maintain(t, 1);}void insert(int& t, int q) {if (t == 0) {t = LEN++;s[t] = 1;p[t] = q;} else  {s[t]++;if (score[q] <= score[p[t]])insert(l[t], q);elseinsert(r[t], q);Maintain(t, score[q] > score[p[t]]);}}int del(int& t, int rk) {s[t]--;if (rk <= s[r[t]])return del(r[t], rk);else if (rk > s[r[t]] + 1)return del(l[t], rk - s[r[t]] - 1);int w = p[t];if (l[t] == 0 || r[t] == 0)t = l[t] + r[t];elsep[t] = del(l[t], rk - s[r[t]]);return w;}int getSub(const char* t) {leaf q = root;for (int i = 0; t[i]; i++)q = q->next[t[i] - 65];return q->sub;}int rank(int t, int q) {if (!t)return 0;if (score[q] == score[p[t]] && seq[p[t]] == seq[q])return s[r[t]] + 1;if (score[q] < score[p[t]])return rank(l[t], q) + s[r[t]] + 1;if (score[q] > score[p[t]])return rank(r[t], q);if (seq[q] < seq[p[t]])return rank(r[t], q);return rank(l[t], q) + s[r[t]] + 1;}int getSubByRank(int t, int rk) {if (rk > s[t])return 0;if (rk <= s[r[t]])return getSubByRank(r[t], rk);if (rk > s[r[t]] + 1)return getSubByRank(l[t], rk - s[r[t]] - 1);return p[t];}void update(const char* t, int sc, int sq) {leaf p = root;int i;for (i = 0; t[i]; i++) {int pos = t[i] - 65;if (p->next[pos] == NULL)p->next[pos] = getNode();p = p->next[pos];}if (p->sub == 0) {p->sub = len;strcpy(name[len], t);score[len] = sc;seq[len] = sq;insert(T, len);len++;} else {int rk = rank(T, p->sub);del(T, rk);score[p->sub] = sc;seq[p->sub] = sq;insert(T, p->sub);}}int main() {int sq, n, sc;char t[0x10];root = getNode();scanf("%d", &n);for (sq = 1; sq <= n; sq++) {scanf("%s", t);if (t[0] == '+') {scanf("%d", &sc);update(t + 1, sc, sq);} else if (isalpha(t[1])){int pos = getSub(t + 1);printf("%d\n", rank(T, pos));} else {int rk[0x10], length = 1, i;sscanf(t + 1, "%d", &i);for (length = 0; length < 10; length++, i++) {rk[length] = getSubByRank(T, i);if (!rk[length])break;}for (i = 0; i < length - 1; i++)printf("%s ", name[rk[i]]);printf("%s\n", name[rk[i]]);}}return 0;}

解题代码(Hash):

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <ctype.h>#include <iostream>using namespace std;const int maxn = 250050;char name[maxn][12];int score[maxn], seq[maxn];int T = 0, LEN = 1;int s[maxn], l[maxn], r[maxn], v[maxn], p[maxn], c[maxn];inline unsigned hashing(const char* t) {unsigned i, hs = 0, sd = 13131;for (i = 0; t[i]; i++)hs = hs * sd + t[i];return hs % 250007 + 1;}inline void l_rt(int& t) {int k = r[t]; r[t] = l[k];l[k] = t; s[k] = s[t];s[t] = s[l[t]] + s[r[t]] + 1;t = k;}inline void r_rt(int& t) {int k = l[t]; l[t] = r[k];r[k] = t; s[k] = s[t];s[t] = s[l[t]] + s[r[t]] + 1;t = k;}void Maintain(int& t, int flag) {if (flag == 0) {if (s[l[l[t]]] > s[r[t]])r_rt(t);else if (s[r[l[t]]] > s[r[t]])l_rt(l[t]), r_rt(t);elsereturn;} else {if (s[r[r[t]]] > s[l[t]])l_rt(t);else if (s[l[r[t]]] > s[l[t]])r_rt(r[t]), l_rt(t);elsereturn;}Maintain(l[t], 0);Maintain(r[t], 1);Maintain(t, 0);Maintain(t, 1);}void insert(int& t, int sc, int q, int sq) {if (t == 0) {t = LEN++;s[t] = 1; v[t] = sc;p[t] = q; c[t] = sq;} else {s[t]++;if (sc <= v[t])insert(l[t], sc, q, sq);elseinsert(r[t], sc, q, sq);Maintain(t, sc > v[t]);}}int del(int& t, int rk, int& q, int& sq) {s[t]--;if (rk <= s[r[t]])return del(r[t], rk, q, sq);if (rk > s[r[t]] + 1)return del(l[t], rk - s[r[t]] - 1, q, sq);int w = v[t];q = p[t]; sq = c[t];if (l[t] == 0 || r[t] == 0)t = l[t] + r[t];elsev[t] = del(l[t], rk - s[r[t]], p[t], c[t]);return w;}int getSub(const char* t) {int i = hashing(t);while (seq[i] && strcmp(t, name[i])) i++;return i;}int rank(int t, int sc, int sq) {if (!t)return 0;if (sc == v[t] && c[t] == sq)return s[r[t]] + 1;if (sc < v[t])return rank(l[t], sc, sq) + s[r[t]] + 1;if (sc > v[t])return rank(r[t], sc, sq);if (sq < c[t])return rank(r[t], sc, sq);return rank(l[t], sc, sq) + s[r[t]] + 1;}int getSubByRank(int t, int rk) {if (rk > s[t])return 0;if (rk <= s[r[t]])return getSubByRank(r[t], rk);if (rk > s[r[t]] + 1)return getSubByRank(l[t], rk - s[r[t]] - 1);return p[t];}void update(const char* t, int sc, int sq) {int i = getSub(t);if (seq[i] == 0) {strcpy(name[i], t);} else {int rk = rank(T, score[i], seq[i]), tmp;del(T, rk, tmp, tmp);}score[i] = sc;seq[i] = sq;insert(T, sc, i, sq);}int main() {int sq, n, sc;char t[0x10];scanf("%d", &n);for (sq = 1; sq <= n; sq++) {scanf("%s", t);if (t[0] == '+') {scanf("%d", &sc);update(t + 1, sc, sq);} else if (isalpha(t[1])){int pos = getSub(t + 1);printf("%d\n", rank(T, score[pos], seq[pos]));} else {int rk[12], length = 1, i;sscanf(t + 1, "%d", &i);for (length = 0; length < 10; length++, i++) {rk[length] = getSubByRank(T, i);if (!rk[length])break;}for (i = 0; i < length - 1; i++)printf("%s ", name[rk[i]]);printf("%s\n", name[rk[i]]);}}return 0;}