• [模板]离散化


    离散化基于这样一种思想:当想要存储的数据的量较小,而数值较大,并且操作对象是数值时,使用数值的排名来代表数值进行操作.

    与哈希算法很相似,不过这种算法一定不会发生冲突,但是预处理复杂度为O(NlogN),单次查询的复杂度是O(logN).

     给出的数在32位有符号整数范围内.

    如果每当一个数字第一次出现时,将其记录为已出现,当下一次出现时就可以忽略它了.

    为了进行这样的记录,使用排名代表数字,使得每个数字(重复视为同一个数字)与其排名形成一一对应关系.使用discrete函数构建这种关系:

    // 假设给定的ind个数据已经复制到了dis数组中
    void discrete() {    // O(NlogN)
        sort(dis + 1, dis + 1 + ind);
        ind = unique(dis + 1, dis + 1 + ind) - dis - 1;    // unique的复杂度是O(N)
    }

    现在dis数组中就有了排序并去重后的数字,排名为i的数字为dis[i]的值.之后处理dis[i]时用i代替之.

    例如,读取到一个数字123456789,使用query函数获取其排名:

    // O(logN)
    int query(int x) { return lower_bound(dis + 1, dis + 1 + ind, x) - dis; }

    假设query(123456789)返回了5,那么检查排名为5的数字是否已经出现过了(used[5] == true),如果没有出现过就输出dis[5]并标记为已出现,否则直接读取下一个数字.

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    #define SIZE 50000
    
    int s[SIZE + 10], dis[SIZE + 10], idx;
    bool used[SIZE + 10];
    
    inline int read() {
        char ch = getchar();
        int x = 0, f = 1;
        while (ch > '9' || ch < '0') {
            if (ch == '-') f = -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9') {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        return x * f;
    }
    void discrete() {
        sort(dis + 1, dis + 1 + idx);
        idx = unique(dis + 1, dis + 1 + idx) - dis - 1;
    }
    int query(int x) { return lower_bound(dis + 1, dis + 1 + idx, x) - dis; }
    
    void solve() {
        int n = read();
        idx = 0;
        memset(used, 0, sizeof(bool) * (n + 1));
        for (int i = 1; i <= n; i++) {
            s[i] = read();
            dis[++idx] = s[i];
        }
        discrete();
    
        for (int i = 1; i <= n; i++) {
            int ns = query(s[i]);
            if (!used[ns]) {
                printf("%d ", s[i]);
                used[ns] = true;
            }
        }
        puts("");
    }
    
    int main() {
        int t;
        t = read();
        while (t--) solve();
    
        return 0;
    }
    P4305
  • 相关阅读:
    55种网页常用小技巧(javascript) (转)
    如何利用RadioButtonList实现datagrid列的单选 (转)
    实现数据分类汇总的SQL语句 (转)
    在ASP.Net中两种利用CSS实现多界面的方法. (转)
    ASP.NET 中 Session 实现原理浅析 [1] 会话的建立流程
    用户控件中使用客户端脚本的控件名称问题 (转)
    快速理解.NET Framework[翻译] (转)挺不错的翻译
    table的宽度,单元格内换行问题 (转)
    实现类似Windows资源管理器的DataGrid(转)
    vs.net web项目使用visual source safe进行源代码管理(转)
  • 原文地址:https://www.cnblogs.com/Gaomez/p/14255620.html
Copyright © 2020-2023  润新知