zoukankan      html  css  js  c++  java
  • 【HAOI2008】排名系统

    Description

    设计一种数据结构,支持给指定点插入元素并覆盖先前的元素、查询某一点的排名、输出从任意排名之后的10名。

    Solution

    采用Splay实现

    关于读入的字符串,我们可以哈希然后将哈希值丢到map里,这样就可以给每一个字符串一个编号,方便在Splay上操作。

    关于插入和删除以及查询操作,都是Splay的基本操作,在此不再赘述。

    关于输出答案,我们这样思考:根据BST的性质,当前点的右子树的值一定大于当前点,左子树的值一定小于当前点,也就意味着我们对这棵树进行一次中序遍历就可以得到一个有序序列。那么我们输出答案也是如此,先在右子树中递归输出,在输出当前节点,再进入左子树,同时开一个计数器记录当前输出了多少答案即可。

    为了维护Splay的随机性,我们每执行200次操作就随机一个节点并将它延伸到树根。

    Code

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef unsigned long long ull;
      4 const int INF = 2147483647;
      5 const ull mod = 212370440130137957ll;
      6 inline int read() {
      7     int ret = 0, op = 1;
      8     char c = getchar();
      9     while (!isdigit(c)) {
     10         if (c == '-') op = -1; 
     11         c = getchar();
     12     }
     13     while (isdigit(c)) {
     14         ret = ret * 10 + c - '0';
     15         c = getchar();
     16     }
     17     return ret * op;
     18 }
     19 inline ull rethash(char *aa) {
     20     ull ret = 0;
     21     int l = strlen(aa + 1);
     22     for (register int i = 1; i <= l; ++i)
     23         ret = (ret * 131 + aa[i]) % mod;
     24     return ret;
     25 }
     26 inline int retnum(char *aa) {
     27     int ret = 0;
     28     int l = strlen(aa + 1);
     29     for (register int i = 1; i <= l; ++i) 
     30         ret = ret * 10 + aa[i] - '0';
     31     return ret;
     32 }
     33 map <ull, int> hash;
     34 int n, root, tot, len[250010];
     35 struct Splay {
     36     int fa, sum, ch[2], val;
     37 } a[250010];
     38 char in[20], name[250010][20];
     39 void update(int now) {
     40     a[now].sum = a[a[now].ch[0]].sum + a[a[now].ch[1]].sum + 1;
     41 } 
     42 void connect(int x, int fa, int op) {
     43     a[x].fa = fa;
     44     a[fa].ch[op] = x;
     45 }
     46 void rotate(int x) {
     47     int y = a[x].fa;
     48     int z = a[y].fa;
     49     int xson = a[y].ch[1] == x;
     50     int yson = a[z].ch[1] == y;
     51     int B = a[x].ch[xson ^ 1];
     52     connect(B, y, xson); connect(y, x, xson ^ 1); connect(x, z, yson);
     53     update(y); update(x);
     54 }
     55 void splay(int from, int to) {
     56     while (a[from].fa != to) {
     57         int y = a[from].fa;
     58         int z = a[y].fa;
     59         if (z != to) (a[y].ch[0] == from) ^ (a[z].ch[0] == y) ? rotate(from) : rotate(y);
     60         rotate(from);
     61     }
     62     if (to == 0) root = from;
     63 }
     64 void insert(int val, int x) {
     65     int now = root, fa = 0;
     66     while (1) {
     67         if (!now) {
     68             a[x].val = val;
     69             a[x].fa = fa;
     70             a[x].sum = 1;
     71             a[fa].ch[val > a[fa].val] = x;
     72             splay(x, 0);
     73             return ;
     74         }
     75         fa = now;
     76         now = a[now].ch[val > a[now].val];
     77     }
     78 }
     79 int query(int x) {
     80     int now = root;
     81     while (1) {
     82         if (x <= a[a[now].ch[0]].sum) now = a[now].ch[0];
     83         else {
     84             x -= a[a[now].ch[0]].sum + 1;
     85             if (!x) return now;
     86             now = a[now].ch[1];
     87         }
     88     }
     89 }
     90 void del(int x) {
     91     splay(x, 0);
     92     int size = a[a[root].ch[0]].sum;
     93     int l = query(size);
     94     int r = query(size + 2);
     95     splay(l, 0); splay(r, l);
     96     a[r].ch[0] = 0;
     97     update(r); update(l);
     98     a[x].fa = a[x].val = a[x].sum = 0;
     99 }
    100 void print(int now, int &sum) {
    101     if (sum >= 10) return ;
    102     if (a[now].ch[1]) print(a[now].ch[1], sum);
    103     if (sum >= 10) return ;
    104     if (now > 2) {
    105         sum++;
    106         for (register int i = 1; i < len[now]; ++i)
    107             putchar(name[now][i]);
    108         putchar(' ');
    109     }
    110     if (a[now].ch[0]) print(a[now].ch[0], sum);
    111 }
    112 int main() {
    113     srand(20040312);
    114     n = read();
    115     insert(-INF, ++tot); insert(INF, ++tot);
    116     for (register int i = 1; i <= n; ++i) {
    117         scanf("%s", in);
    118         if (in[0] == '+') {
    119             ull ret = rethash(in); int x = read();
    120             if (hash[ret]) {
    121                 del(hash[ret]);
    122                 insert(x, hash[ret]);
    123             }
    124             else {
    125                 insert(x, hash[ret] = ++tot);
    126                 for (register int i = 1; i < strlen(in); ++i) name[tot][i] = in[i];
    127                 len[tot] = strlen(in);
    128             }
    129         }
    130         else if (isdigit(in[1])) {
    131             int x = retnum(in);
    132             int l = query(tot - x + 1);
    133             splay(l, 0);
    134             int sum = 0;
    135             print(a[l].ch[0], sum);
    136             puts("");
    137         }
    138         else {
    139             ull ret = rethash(in);
    140             splay(hash[ret], 0);
    141             printf("%d
    ", a[a[root].ch[1]].sum);
    142         }
    143         if (i % 200 == 0) splay(rand() % tot + 1, 0);
    144     }
    145     return 0;
    146 }
    AC Code
  • 相关阅读:
    firefly rk3399 增加 HL340 驱动(编译内核)
    STM32移植ROS发布超声波信息
    路径规划基础A*算法
    ROS融合IMU笔记
    a2 任意角度选取设置
    如何用代码设置机器人初始坐标实现 2D Pose Estimate功能
    APP 链接ROS时出现pymongo.errors.ServerSelectionTimeoutError: localhost:27017 错误
    基于opencv+python的二维码识别
    SAP UI5学习笔记之(二)熟悉的HelloWorld
    SAP UI5学习笔记之(一)初识SAP UI5
  • 原文地址:https://www.cnblogs.com/shl-blog/p/11278875.html
Copyright © 2011-2022 走看看