首页 > 编程语言 >基础算法——异或哈希算法 学习笔记

基础算法——异或哈希算法 学习笔记

时间:2024-11-27 15:45:51浏览次数:10  
标签:int u64 异或 算法 哈希 权值 hashing

异或哈希算法

思想

我们关注一个区间内出现了什么数字。

因此,我们对每一个数字赋一个随机权值,

然后对这个权值进行一系列操作,例如前缀 \(\operatorname{xor}\) 等。

对于两个序列,通过 Hash 的方式判断即可。

同时,也可用于满足某些条件的子序列数量的问题。

我们可以通过 Hash 的方式找到前面满足某些条件的数,来匹配子序列。

例题

区间判断

AtCoder [ABC250E] Prefix Equality

题目描述:

给定序列 \(A,B\),询问 \(A\) 的前 \(x\) 个数和 \(B\) 的前 \(y\) 个数去重后是否相同。

做法:

我们对每一个数赋一个随机权值,

将序列中第一次出现的这个数赋为权值,后面的都赋为 \(0\)。

那么我们只需要判断两个前缀异或和是否相同即可。

使用 mt19937_64 生成比较强的随机数,冲突概率较小。

  • 代码
    using u64 = uint64_t;
    
    mt19937_64 rnd_big(114514);
    
    int n;
    
    u64 W[N];
    
    u64 A[N], B[N];
    
    unordered_set<int> appA, appB;
    unordered_map<int, u64> hashing;
    
    u64 get_hashing(int x) {
        return hashing.count(x) ? hashing[x] : hashing[x] = rnd_big();
    }
    
    void Main() {
        cin >> n;
        for (int i = 1; i <= n; ++i) {
            int x;
            cin >> x;
            if (appA.count(x))
                A[i] = A[i - 1];
            else
                A[i] = A[i - 1] ^ get_hashing(x), appA.insert(x);
        }
        for (int i = 1; i <= n; ++i) {
            int x;
            cin >> x;
            if (appB.count(x))
                B[i] = B[i - 1];
            else
                B[i] = B[i - 1] ^ get_hashing(x), appB.insert(x);
        }
        int q;
        cin >> q;
        while (q--) {
            int x, y;
            cin >> x >> y;
            puts(A[x] == B[y] ? "Yes" : "No");
        }
    }
    

区间计数

变种

矩阵乘积

来源是 CSP-S 2023 消消乐,用处不大。

但是这引出了类似异或和的一个特有做法。

设有一个群 \((G,\cdot)\),将元素分为入元素和出元素,令入元素和出元素互为逆元。

那么,如果一个区间 \([l,r]\) 的某种运算的前缀和为单位元了,

那么意味着这个区间的元素可以互相抵消,我们可以将前缀和放到 map 里面记录,

对于每一个 \(S(r)\) 对应的 \(S(l)=S(r),l<r\) 就可以统计满足条件的子区间数量。

标签:int,u64,异或,算法,哈希,权值,hashing
From: https://www.cnblogs.com/RainPPR/p/18572452

相关文章

  • 《基于des算法的企业用户数据安全》
    大家好,我是陈辰学长,一名在Java圈辛勤劳作的码农。今日要和大家分享的是一款、《基于des算法的企业用户数据安全》毕业设计项目。项目源码以及部署相关事宜,请联系陈辰学长,文末会附上联系信息哦。......
  • 如何优化排序算法
    ruru对于只有四个元素的数组,选择排序和冒泡排序的效率差异不大,因为它们的复杂度都是O(n^2),但由于n很小,实际运行时间差异并不明显。然而,对于优化,我们可以考虑以下几种方法:冒泡排序:由于数组很小,冒泡排序可以是一个简单且直观的选择。插入排序:对于小数组,插入排序通常比选择排......
  • 如何识别算法交易策略 第一篇:个人交易偏好和交易策略灵感
    全是干货!在本文中,我想向你介绍我自己用来寻找有利可图的算法交易策略的方法。我们今天的目标是详细了解如何发现、评估和选择这些系统。我会解释,寻找策略既涉及个人偏好,也涉及策略表现;如何确定用于测试的历史数据类型和数量;如何以客观的态度评估交易策略;以及如何进一步推进......
  • 记一次unicorn半自动化逆向——还原某东sign算法
    分析准备集成so文件为了方便分析和调试,我选择了主动集成生成sign的so文件到自己写的apk中,然后主动调用。可能是gradle版本的问题,搜索到的文章大都无效,踩坑十分多。其实配置很简单,在src/main/目录下建立jniLibs/armeabi-v7a/目录,把so文件放在里面。然后配置好build.gradle......
  • 《算法导论》英文版前言To the teacher第1段研习录
    【英文版】TotheteacherWehavedesignedthisbooktobebothversatileandcomplete.Youshouldfinditusefulforavarietyofcourses,fromanundergraduatecourseindatastructuresupthroughagraduatecourseinalgorithms.Becausewehaveprovided......
  • 数学期望在算法中的应用
    数学期望在算法中的应用数学期望是概率论和统计学中的一个核心概念,主要用于描述所有数据的平均值或者是中心趋势。在计算机算法竞赛中,期望算法属于一个中高等难度的算法,在程序设计中发挥着至关重要的作用。在近些年的CSP/USACO等国际知名算法竞赛中,期望和期望动态规划等算法常......
  • MATLAB 实现遗传算法优化随机森林(GA-RF)进行多输入单输出回归预测
    目录1.项目概述...11.1背景...11.2模型描述...12.项目设计...12.1数据生成...12.2遗传算法优化随机森林模型...22.3模型训练与预测...32.4结果评估与可视化...33.完整代码...44.项目总结...6未来改进方向...6参考资料...6以下是一个使用M......
  • MATLAB 实现 SSA-GRU和 GRU(门控循环单元)结合麻雀算法优化时间序列预测
    目录1.项目概述...11.1背景...11.2模型描述...12.项目设计...12.1数据生成...12.2TTA分解...22.3GTT模型构建...32.4麻雀算法优化GTT超参数...32.5模型训练与预测...42.6结果评估与优化前后比较...43.完整代码...54.项目总结...7未来......
  • 复杂交通模式中电梯调度算法的方向优化研究(Matlab代码实现)
      ......
  • 异或最长路(线性基应用)
    首先异或最长路不能用Bellman-Ford,因为异或不满足加法传递性,局部最优可能推不出整体最优,而且可能出现类似“负环”的情况,走不出来。一般要用线性基解决这一类问题。我们可以把路径拆成一条链(蓝色)和若干个环(灰色)。我们可以走一条红色的路径到达一个环,转一圈然后原路返回,这样红色......